Mohammad Itani
03/10/2025, 2:59 PMRequestScope
while handling concurrent POST requests in a Ktor application. The application is set up to use Koin for dependency injection and RequestScope
for isolating dependencies per request. However, when two requests are made concurrently, one of them fails with the following error:
Failed to resolve dependency 'interface <DependencyName>' because of 'Scope 'org.koin.ktor.plugin.RequestScope@1453707788' is closed'
Upon logging the scope IDs, we noticed that the scope initialized for the request is different from the one being logged during the error. For example:
• Scope initialized: org.koin.ktor.plugin.RequestScope@1527158232
• Scope during error: org.koin.ktor.plugin.RequestScope@1453707788
To debug further, I added a breakpoint in the setupKoinScope
function in the Koin-Ktor library:
internal fun PluginBuilder<KoinApplication>.setupKoinScope(koinApplication: KoinApplication) {
// Scope Handling
on(CallSetup) { call ->
val scopeComponent = RequestScope(koinApplication.koin)
call.attributes.put(KOIN_SCOPE_ATTRIBUTE_KEY, scopeComponent.scope)
}
on(ResponseSent) { call ->
call.attributes[KOIN_SCOPE_ATTRIBUTE_KEY].close()
}
}
I observed that the scope ID logged in on(CallSetup)
is not the same as the one logged in on(ResponseSent)
. This suggests that the scope is being replaced or recreated during the request lifecycle, which could explain the mismatch and the "scope is closed" error.
1. Has anyone encountered a similar issue with Koin's RequestScope
in a Ktor application, where the scope ID changes during the request lifecycle?
2. What could cause the RequestScope
to be replaced or recreated between on(CallSetup)
and on(ResponseSent)
?
3. How can I ensure that the RequestScope
remains consistent and properly tied to the request lifecycle, especially in a concurrent environment?
Any insights or suggestions would be greatly appreciated!Seri
03/10/2025, 4:01 PMMohammad Itani
03/12/2025, 1:25 AM