Expected Behavior
Concurrent requests arriving during cold start (empty JWK cache) should coalesce into a single HTTP call to the JWKS endpoint. It seems like the intension was that this already should work because of the cache() reactive operator.
IMO this would also solve the requirment for a pre fetch because it would not be necessary if there would not be massive parallel calls on cold start.
Current Behavior
Each concurrent request creates its own Mono in getJWKSet(). Since .cache() only deduplicates subscriptions to the same instance, N concurrent requests produce N separate HTTP calls, saturating the Reactor Netty connection pool. This had lead to serious problems on our side. This had made on service almost completely being stuck on instant high at cold start (which is quite common if you would scale up some new pods in kubernetes because of too high pressure of the current pods)
Context
ReactiveRemoteJWKSource.getJWKSet() - the method that fetches and caches the JWK set from the IdP's JWKS endpoint.
What are you trying to accomplish:
Ensure that concurrent JWKS fetches during cold start share a single HTTP call via atomic Mono coalescing, preventing connection pool saturation.
** solution**
I already provide a fix for it in a PR.
The tests i have created would shown that in the old code it would call jwks multiple times at once on cold start.
With the fix it's only 1 time, which is then a 'shared' Mono until it's finished.
Here is the PR:
#19069
** related**
This seems to be related here, and IMO i think this would not be longer required if this thundering herd issue would be resolved:
#9646
Expected Behavior
Concurrent requests arriving during cold start (empty JWK cache) should coalesce into a single HTTP call to the JWKS endpoint. It seems like the intension was that this already should work because of the
cache()reactive operator.IMO this would also solve the requirment for a pre fetch because it would not be necessary if there would not be massive parallel calls on cold start.
Current Behavior
Each concurrent request creates its own Mono in getJWKSet(). Since .cache() only deduplicates subscriptions to the same instance, N concurrent requests produce N separate HTTP calls, saturating the Reactor Netty connection pool. This had lead to serious problems on our side. This had made on service almost completely being stuck on instant high at cold start (which is quite common if you would scale up some new pods in kubernetes because of too high pressure of the current pods)
Context
ReactiveRemoteJWKSource.getJWKSet() - the method that fetches and caches the JWK set from the IdP's JWKS endpoint.
What are you trying to accomplish:
Ensure that concurrent JWKS fetches during cold start share a single HTTP call via atomic Mono coalescing, preventing connection pool saturation.
** solution**
I already provide a fix for it in a PR.
The tests i have created would shown that in the old code it would call jwks multiple times at once on cold start.
With the fix it's only 1 time, which is then a 'shared' Mono until it's finished.
Here is the PR:
#19069
** related**
This seems to be related here, and IMO i think this would not be longer required if this thundering herd issue would be resolved:
#9646