Synchronizacja w require

This commit is contained in:
Adam Lemiesz 2025-01-03 19:08:01 +01:00
parent cda8de041d
commit b0a157582e
4 changed files with 23 additions and 20 deletions

View File

@ -4,7 +4,7 @@ plugins {
allprojects {
group = "org.lemiesz"
version = "1.4.5"
version = "1.4.7"
}
//nexusPublishing {

View File

@ -1,2 +0,0 @@
actual val firstElement: Int = 2
actual val secondElement: Int = 3

View File

@ -36,7 +36,7 @@ fun <T : Any> ModuleScope.req(
disposable: () -> Module.DisposableProvider0<T>
): T = disposable().let {
val s = InjectScope0(module = it)
disposables.add(s)
addScope(s)
s.get()
}
@ -45,6 +45,7 @@ fun <T : Any, P> ModuleScope.req(
disposable: () -> Module.DisposableProvider1<T, P>
): T = disposable().let {
val s = InjectScope1(it, param)
disposables.add(s)
addScope(s)
s.get()
}

View File

@ -5,6 +5,8 @@ import kotlinx.atomicfu.AtomicInt
import kotlinx.atomicfu.atomic
import kotlinx.atomicfu.updateAndGet
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.lemiesz.require.log.simpleName
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KClass
@ -12,7 +14,8 @@ import kotlin.reflect.KProperty
open class ModuleScope {
private var _scope: CoroutineScope = CoroutineScope(EmptyCoroutineContext)
val disposables = mutableListOf<InjectScope<*>>()
protected val disposables = mutableListOf<InjectScope<*>>()
protected val mutex = Mutex()
val scope: CoroutineScope
@ -22,12 +25,20 @@ open class ModuleScope {
if (v is Model) v.onStart()
}
protected fun finishModuleScope(v :Any?) {
protected fun finishModuleScope(v: Any?) {
val s = _scope
_scope = CoroutineScope(EmptyCoroutineContext)
if (v is Model) v.onStop()
s.cancel()
}
fun addScope(s: InjectScope<*>) {
scope.launch {
mutex.withLock {
disposables.add(s)
}
}
}
}
open class Module {
@ -38,7 +49,6 @@ open class Module {
private fun <V : Any> create(v: () -> V): V {
return v().also {
initModuleScope(it)
logInj { "create ${it::class.simpleName}" }
}
}
@ -48,16 +58,17 @@ open class Module {
value = it
}
fun clean() {
logInj { "clean ${disposables.count()}" }
suspend fun clean() {
val v: Any? = value
value = null
finishModuleScope(v)
disposables.forEach {
logInj { "cleanDispose ${it.simpleName}" }
mutex.withLock {
disposables.toTypedArray().also {
disposables.clear()
}
}.forEach {
it.dispose()
}
disposables.clear()
}
}
@ -78,12 +89,10 @@ open class Module {
fun _get(): T {
subCount.incrementAndGet()
r = info.getOrCreate(_function)
logInj { "get ${r.simpleName} $subCount" }
return r!!
}
fun _dispose() {
logInj { "dispose ${r.simpleName} $subCount" }
subCount.updateAndGet {
if (it > 0) it - 1 else 0
}.takeIf {
@ -91,7 +100,6 @@ open class Module {
}?.apply {
makeClean()
}
logInj { "disposee ${r.simpleName} $subCount" }
}
@OptIn(DelicateCoroutinesApi::class)
@ -100,7 +108,6 @@ open class Module {
disposeDelay.takeIf { it > 0 }?.apply {
delay(disposeDelay)
}
logInj { "makeClean $subCount $disposeDelay" }
info.apply {
clean()
destruction()
@ -121,7 +128,6 @@ open class Module {
val keys = IsoMutableMap<P1, Pair<AtomicInt, InjInfo>>()
fun _get(p1: P1): T {
logInj { "get1 ${p1.simpleName}" }
return keys.getOrPut(p1) { atomic(0) to InjInfo() }.let { (a, info) ->
a.incrementAndGet()
info.getOrCreate { creation(p1) }
@ -129,7 +135,6 @@ open class Module {
}
fun _dispose(key: P1) {
logInj { "dispose ${key.simpleName}" }
keys[key]?.let { (a, info) ->
a.updateAndGet { if (it > 0) it - 1 else it }
.takeIf { it == 0 }
@ -145,7 +150,6 @@ open class Module {
disposeDelay.takeIf { it > 0 }?.apply {
delay(disposeDelay)
}
logInj { "makeClean $key $disposeDelay" }
info.apply {
keys.remove(key)
clean()