Commits
Tarun Sukhani authored 1b3cf18a301
fix(vt): bypass Javaflow await on virtual threads to preserve request scope Four Controller.await(...) overloads gain a VirtualThreadConfig.isInvokerEnabled() short-circuit that skips the Javaflow continuation + Suspend/resume dance under VT mode and instead blocks the same virtual thread for the wait. The platform-thread pattern (continuation capture → Suspend → resume on a fresh Invocation) relies on the resumed Invocation getting its own ThreadLocals re-populated. Under VT mode the resumption lands on a different VT with empty ThreadLocals — orphaning every request-scoped resource the original VT held, most importantly the JPA EntityManager and its leased JDBC connection. Blocking the same VT directly is cheap (Loom yields the carrier on Thread.sleep and future.get) and keeps Request.current(), the EntityManager, and any other per-request ThreadLocal-bound state intact end-to-end. Affected overloads: await(int millis) — Thread.sleep instead of Continuation.suspend await(int millis, F.Action0 callback) — Thread.sleep then inline callback.invoke() await(Future<T>) — future.get() returned synchronously await(Future<T>, F.Action<T> callback) — future.get() then inline callback.invoke(result) InterruptedException is rethrown as UnexpectedException after restoring the interrupt flag; ExecutionException unwraps RuntimeExceptions and re-wraps the rest. The platform-thread paths are unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>