When my request thread transfers scope to a child thread thread, then that thread thread attempts to transfer the scope to a grandchild thread it is possible to introduce a deadlock.
Here is the most simple example I could make. It doesn't actually create an injector or resolve request scoped objects but the underlying deadlock is the same.
@Test
@Timeout(value = 1, threadMode = ThreadMode.SEPARATE_THREAD)
void testScopeTransferSupplier() throws Exception {
String a = UUID.randomUUID().toString();
Supplier<String> supplier = () -> a;
try (final RequestScoper.CloseableScope ignored = ServletScopes.scopeRequest(Map.of()).open()) {
final Callable<String> transferred = ServletScopes.transferRequest(supplier::get);
final Supplier<String> transferredSupplier = () -> {
try {
return transferred.call();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
// should not happen, but required since we converted this to a callable
throw new CompletionException(e);
}
};
assertEquals(a, CompletableFuture.supplyAsync(transferredSupplier).join());
}
}
What are our options when we have nested async calls that require request scoped objects in our application code?
When my request thread transfers scope to a child thread thread, then that thread thread attempts to transfer the scope to a grandchild thread it is possible to introduce a deadlock.
Here is the most simple example I could make. It doesn't actually create an injector or resolve request scoped objects but the underlying deadlock is the same.
What are our options when we have nested async calls that require request scoped objects in our application code?