spring-projects / spring-projects/spring-security

WebSessionServerRequestCache should avoid needless blocking operations

Open
#9,200 6 comments 2 reactions 1 assignee View on GitHub

@jzheaux is already working on this.

Since Nov 24, 2020.

in: web status: blocked type: enhancement
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Using Spring Cloud Gateway and disabling the request cache we see different behaviour under load in our application: more latency and timeouts occur.

To disable we call: requestCache().disable()

Investigation showed that our custom filters in Spring Gateway run on a boundedElastic thread with request cache enabled and on the reactor-http-nio-* thread when request cache is disabled.

It seems that some blocking code in one of our filters is then causing the latency and timeouts on the reactor-http-nio-* threads and impact performance behaviour. (We are also looking into fixing this.)

Spring boot: 2.3.5.RELEASE
Spring cloud dependencies: Hoxton.SR8
spring-cloud-services-dependencies: 3.1.5.RELEASE

Not sure if spring-security is the correct place to post this issue, can also be a gateway or framework issue?

To Reproduce
With block hound enabled, we see no stacktrace for blocking code with request cache enabled (on bounded elastic thread), but we see the stacktrace for blocking code with request cache disabled (on reactor-http-nio thread).

Also, in logging you can see the thread that is used, which is different when cache is disabled.

Expected behaviour
Same threading behaviour expected when request cache is disabled/enabled.

No bounded elastic threads expected: spring cloud gateway threads should preferably not run on boundedElastic threads, as described here: https://github.com/spring-cloud/spring-cloud-gateway/issues/1229

It might be related to this code org.springframework.web.server.session.InMemoryWebSessionStore#createWebSession from Spring framework:

@Override
	public Mono<WebSession> createWebSession() {

                 ...
		return Mono.<WebSession>fromSupplier(() -> new InMemoryWebSession(now))
				.subscribeOn(Schedulers.boundedElastic()); <== seem to cause boundedElastic Thread 
	}

With this subscribeOn call, it looks like more code is running on the bounded elastic thread than only the "new InMemoryWebSession(now)". The explicit subscribeOn was added for this issue: https://github.com/spring-projects/spring-framework/issues/24027

From: https://projectreactor.io/docs/core/release/reference/#schedulers:
"Obtaining a Flux or a Mono does not necessarily mean that it runs in a dedicated Thread. Instead, most operators continue working in the Thread on which the previous operator executed. Unless specified, the topmost operator (the source) itself runs on the Thread in which the subscribe() call was made."

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.