-
-
Notifications
You must be signed in to change notification settings - Fork 727
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
[core] Ensure onClose callbacks are invoked in reversed initialization order #2020
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,8 @@ | |
|
||
package org.koin.core.instance | ||
|
||
import co.touchlab.stately.concurrency.AtomicBoolean | ||
import co.touchlab.stately.concurrency.AtomicLong | ||
import org.koin.core.definition.BeanDefinition | ||
import org.koin.core.error.InstanceCreationException | ||
import org.koin.core.parameter.ParametersHolder | ||
|
@@ -28,8 +30,12 @@ import org.koin.mp.Lockable | |
/** | ||
* Koin Instance Holder | ||
* create/get/release an instance of given definition | ||
* | ||
* Implements [Comparable] to provide factories soring by instance creation order | ||
*/ | ||
abstract class InstanceFactory<T>(val beanDefinition: BeanDefinition<T>) : Lockable() { | ||
abstract class InstanceFactory<T>(val beanDefinition: BeanDefinition<T>) : Lockable(), Comparable<InstanceFactory<*>> { | ||
private val instanceCreationOrderSet = AtomicBoolean(false) | ||
private var instanceCreationOrderPosition = Long.MAX_VALUE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current design ties a child instance natural comparison to its insertion ordering within a parent collection. A Instead, what if the Here's a possible approach:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same thought here. Consider another proposal @shchuko |
||
|
||
/** | ||
* Retrieve an instance | ||
|
@@ -47,17 +53,36 @@ abstract class InstanceFactory<T>(val beanDefinition: BeanDefinition<T>) : Locka | |
context.logger.debug("| (+) '$beanDefinition'") | ||
try { | ||
val parameters: ParametersHolder = context.parameters ?: emptyParametersHolder() | ||
return beanDefinition.definition.invoke( | ||
val instance = beanDefinition.definition.invoke( | ||
context.scope, | ||
parameters, | ||
) | ||
if (instanceCreationOrderSet.compareAndSet(false, true)) { | ||
instanceCreationOrderPosition = INSTANCE_CREATION_ORDER_COUNTER.incrementAndGet() | ||
|
||
// just to be sure that counter provides normal values | ||
check(instanceCreationOrderPosition >= 0) { | ||
"Unexpected negative instance creation order position" | ||
} | ||
|
||
// it's required to have `Long.MAX_VALUE` instantiations happened to make this check fail, | ||
// which is not likely to happen | ||
check(instanceCreationOrderPosition < Long.MAX_VALUE) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I understand your code comment above and it seems error prone. |
||
"Instance creation order position reached Long.MAX_VALUE" | ||
} | ||
} | ||
return instance | ||
} catch (e: Exception) { | ||
val stack = KoinPlatformTools.getStackTrace(e) | ||
context.logger.error("* Instance creation error : could not create instance for '$beanDefinition': $stack") | ||
throw InstanceCreationException("Could not create instance for '$beanDefinition'", e) | ||
} | ||
} | ||
|
||
override fun compareTo(other: InstanceFactory<*>): Int { | ||
return instanceCreationOrderPosition.compareTo(other.instanceCreationOrderPosition) | ||
} | ||
|
||
/** | ||
* Is instance created | ||
*/ | ||
|
@@ -72,5 +97,6 @@ abstract class InstanceFactory<T>(val beanDefinition: BeanDefinition<T>) : Locka | |
|
||
companion object { | ||
const val ERROR_SEPARATOR = "\n\t" | ||
private val INSTANCE_CREATION_ORDER_COUNTER = AtomicLong(-1) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: sorting