Async Jersey + Kotlin Coroutines
Article Summary
ClassPass engineers were hitting a wall: their Jersey-based APIs couldn't handle traffic spikes without exhausting thread pools. The culprit? Synchronous request processing blocking precious I/O threads.
Dan Murphy from ClassPass Engineering shares how they integrated Jersey's async API with Kotlin coroutines to build more resilient backend services. The team had to solve tricky challenges around connection leaks, logging context, and APM instrumentation.
Key Takeaways
- Async Jersey frees I/O threads immediately, preventing bottlenecks during long-running requests
- Built submitToCoroutine extension to avoid ceremony and prevent connection leaks
- Solved MDC logging context loss using kotlinx-coroutines-slf4j integration
- Custom dispatcher links New Relic transactions across coroutine thread switches
- Result: apps now handle traffic spikes and isolate high-latency endpoint impact
Combining Jersey's async API with Kotlin coroutines made ClassPass services more resilient under load while maintaining observability.
About This Article
ClassPass's Jersey-based services had connection leaks when long-running operations threw exceptions. Client connections stayed open without proper error context, leaving only generic 503 timeouts.
Dan Murphy's team created a submitToCoroutine extension function that wraps AsyncResponse and adds automatic try-catch handling. This ensures exceptions always resume the connection and prevents leaks.
The custom dispatcher implementation connected New Relic transactions across coroutine thread switches. This kept full APM visibility into asynchronous work that had previously gone untracked.