conflicts resolvers customization

This commit is contained in:
2023-10-01 15:28:00 +06:00
parent 9d72d79321
commit 30cf190461
7 changed files with 54 additions and 1 deletions

View File

@@ -0,0 +1,16 @@
package dev.inmo.plagubot
import dev.inmo.micro_utils.fsm.common.State
fun interface OnStartContextsConflictResolver {
/**
* @param old Old state which is currently placed on the [State.context]
* @param new New state pretend to replace [old] one
* @return Should return:
*
* * Null in case when current realization unable to resolve conflict
* * False when current realization knows that [new] [State] must **not** replace [old] one
* * True when current realization knows that [new] [State] must replace [old] one
*/
suspend operator fun invoke(old: State, new: State): Boolean?
}

View File

@@ -0,0 +1,20 @@
package dev.inmo.plagubot
import dev.inmo.micro_utils.fsm.common.State
fun interface OnUpdateContextsConflictResolver {
/**
* This method will be called when [sourceStateWithOldContext] [State.context] and [newStateWithNewContext] are not equal and currently there is
* launched [currentStateOnNewContext] state on the chain with [State.context] from [currentStateOnNewContext]
*
* @param sourceStateWithOldContext Old state where from [newStateWithNewContext] came
* @param newStateWithNewContext New state with changing [State.context] (it is different with [sourceStateWithOldContext] [State.context])
* @param currentStateOnNewContext State which is currently running on [newStateWithNewContext] [State.context]
* @return Should return:
*
* * Null in case when current realization unable to resolve conflict
* * False when [currentStateOnNewContext] **should not** be stopped in favor to [newStateWithNewContext]
* * True when [currentStateOnNewContext] **should** be stopped in favor to [newStateWithNewContext]
*/
suspend operator fun invoke(sourceStateWithOldContext: State, newStateWithNewContext: State, currentStateOnNewContext: State): Boolean?
}

View File

@@ -6,6 +6,7 @@ import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.micro_utils.fsm.common.StatesManager
import dev.inmo.micro_utils.fsm.common.managers.*
import dev.inmo.micro_utils.koin.getAllDistinct
import dev.inmo.plagubot.config.*
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.webhook.deleteWebhook
@@ -94,6 +95,8 @@ data class PlaguBot(
GlobalContext.startKoin(koinApp)
logger.i("Koin started")
lateinit var behaviourContext: BehaviourContext
val onStartContextsConflictResolver = koinApp.koin.getAllDistinct<OnStartContextsConflictResolver>()
val onUpdateContextsConflictResolver = koinApp.koin.getAllDistinct<OnUpdateContextsConflictResolver>()
bot.buildBehaviourWithFSM(
scope = scope,
defaultExceptionsHandler = {
@@ -101,7 +104,8 @@ data class PlaguBot(
},
statesManager = koinApp.koin.getOrNull<StatesManager<State>>() ?: DefaultStatesManager(
koinApp.koin.getOrNull<DefaultStatesManagerRepo<State>>() ?: InMemoryDefaultStatesManagerRepo<State>(),
onStartContextsConflictResolver = { _, _ -> false }
onStartContextsConflictResolver = { old, new -> onStartContextsConflictResolver.firstNotNullOfOrNull { it(old, new) } ?: false },
onUpdateContextsConflictResolver = { old, new, currentNew -> onUpdateContextsConflictResolver.firstNotNullOfOrNull { it(old, new, currentNew) } ?: false }
),
onStateHandlingErrorHandler = koinApp.koin.getOrNull<StateHandlingErrorHandler<State>>() ?: { state, e ->
logger.eS(e) { "Unable to handle state $state" }