-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Async annotation should allow for non-blocking execution with CompletableFuture [SPR-15401] #19964
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Rossen Stoyanchev commented UPDATE: I've redacted my original response... Upon taking a closer look I think I have a better handle on it. The purpose of In other words the |
Rossen Stoyanchev commented One more comment, since ServiceA actually simulates some sleeping before delegating to ServiceB. I don't think |
Nikolay Georgiev commented The Since we have the mechanism of non-blocking @Controller
public class MyController {
@Autowired
private AsyncServiceA asyncServiceA;
@GetMapping('/user-will-wait')
public CompletableFuture<String> userWillWait() {
/* Call service and return the server thread to its pool. The client will get its result when its ready. Thanks Servlet 3. */
return asyncServiceA.a();
}
}
@Service
public class AsyncServiceA {
@Autowired
private AsyncServiceB asyncServiceB;
@ReactiveAsync /* @NonBlockingAsync */
public CompletableFuture<String> a() {
/* Do some stuff. */
CompletableFuture<String> result = asyncServiceB.b()
.thenCompose(/* Do something with the returned value.*/)
/* Do some other asynchronous long running stuff with the result */
return result;
}
}
@Service
public class AsyncServiceB {
@ReactiveAsync /* @NonBlockingAsync */
public CompletableFuture<String> b() {
/* Do some stuff here as well. */
return CompletableFuture.completedFuture("Yeah, I come from another thread.");
}
} Why is that bad idea? I am doing this manually (as shown in SO question description) and it works for me. |
Nikolay Georgiev commented Excuse my bad formatting. I couldn't find the code style block. |
Rossen Stoyanchev commented It's perfectly fine for ServiceA to compose multiple async services: @Service
public class AsyncServiceA {
@Autowired
private AsyncServiceB serviceB;
@Autowired
private AsyncServiceC serviceC;
public CompletableFuture<String> a() {
return serviceB.b().then(serviceC.c());
}
} ServiceA does not need |
Rossen Stoyanchev commented Okay so bottom line is that |
Nikolay Georgiev commented OK, I got your point now. You are completely right. Thank you for spending so much effort to help me. |
Uh oh!
There was an error while loading. Please reload this page.
Nikolay Georgiev opened SPR-15401 and commented
When calling Async methods that have result composed of CompletableFutures Spring blocks the thread execution by calling get() method internally. This breaks the non-blocking nature of CompletableFuture and makes the use of CompletableFuture composition unusable. More details in the StackOverflow question provided.
Reference URL: https://stackoverflow.com/questions/43095014/nested-async-calls-in-spring
Issue Links:
@MessageMapping
handlersThe text was updated successfully, but these errors were encountered: