-
-
Notifications
You must be signed in to change notification settings - Fork 719
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
Parameter resolution is not threadsafe #1537
Comments
Ran into same / similar issue While trying to create a minimal test for that issue i got the @Test
fun `test koin parallel`() = runTest {
val koin = koinApplication {
modules(module {
factoryOf(::TestData)
})
}.koin
val testDataCreators = (0..1000).map {
async(context = Dispatchers.IO) {
it to koin.get<TestData> { parametersOf(TestDataHolder(it)) }
}
}
val testData = testDataCreators.map { it.await() }
testData.forEach {
it.first `should be equal to` it.second.value.value
}
}
data class TestData(val value: TestDataHolder)
data class TestDataHolder(val value: Int) |
Genuine question: does the problem only happens when using Constructor DSL or does it happens with the standard Module DSL too? From @gerbiljames stack-trace and @NoZomIBK code sample, it seems to be a problem related to how Koin does dependency resolution when using Injected Parameters on a multi-thread environment, and hence, it is a broader issue and not due to Constructor DSL usage. |
You're right @marcellogalhardo, I initially thought that the |
I also had the same problem, this fix (#1561) should help |
let's follow on the PR |
Describe the bug
When parameters are supplied (passed in through a
ParametersHolder
) to Koin they get added to_parameterStack
on theScope
, this works fine if only one object is being resolved at a time. If more than one object is being resolved simultaneously on different threads then this resolution breaks down as there is no way to ensure that for each object that the correctParametersHolder
is at the top of the stack. Additionally, if any object fails resolution (usinggetOrNull()
) then the entire stack is cleared, this can cause required parameters to be lost.I've seen this in production with Android Workers, the stack traces look like:
Not all of our workers are initialised using koin, when WorkManager is initialised it attemps to do any work that is pending which causes it to start several workers at once on multiple background threads. If any of these workers are not koin workers then they (correctly) fail resolution and this wipes the parameter stack. Any workers which were still being resolved at this point lose their
WorkerParameters
and this results in the above stacktrace.There's also a possibility that koin could supply the wrong parameters as the stack could be modified by another thread during object resolution.
To Reproduce
This isn't easy to reproduce due to the nature of multi-threading but analysis of the
Scope
code paints a pretty clear picture of whats going on here.Expected behavior
Parameter resolution is always threadsafe, even when using constructor DSL
Koin project used and used version (please complete the following information):
koin-android version 3.3.3
koin-androidx-workmanager version 3.3.3
Additional moduleDefinition
n/a
The text was updated successfully, but these errors were encountered: