1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-11-16 20:10:18 +00:00

Compare commits

...

8 Commits

5 changed files with 58 additions and 14 deletions

View File

@@ -1,5 +1,12 @@
# TelegramBotAPI changelog # TelegramBotAPI changelog
## 4.2.4
* `Core`:
* Fixes in webhook parts adapter
* `BehaviourBuilderWithFSM`:
* Fixes in `DefaultBehaviourContextWithFSM`
## 4.2.3 ## 4.2.3
* `Versions`: * `Versions`:

View File

@@ -6,4 +6,4 @@ kotlin.incremental=true
kotlin.incremental.js=true kotlin.incremental.js=true
library_group=dev.inmo library_group=dev.inmo
library_version=4.2.3 library_version=4.2.4

View File

@@ -10,6 +10,8 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.T
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**
@@ -133,6 +135,9 @@ class DefaultBehaviourContextWithFSM<T : State>(
private val additionalHandlers = mutableListOf<BehaviourWithFSMStateHandlerHolder<*, T>>() private val additionalHandlers = mutableListOf<BehaviourWithFSMStateHandlerHolder<*, T>>()
private var actualHandlersList = additionalHandlers + handlers private var actualHandlersList = additionalHandlers + handlers
protected val statesJobs = mutableMapOf<T, Job>()
protected val statesJobsMutex = Mutex()
override suspend fun launchStateHandling(state: T, handlers: List<CheckableHandlerHolder<in T, T>>): T? { override suspend fun launchStateHandling(state: T, handlers: List<CheckableHandlerHolder<in T, T>>): T? {
return launchStateHandling(state, handlers, onStateHandlingErrorHandler) return launchStateHandling(state, handlers, onStateHandlingErrorHandler)
} }
@@ -164,21 +169,49 @@ class DefaultBehaviourContextWithFSM<T : State>(
statesManager.endChain(state) statesManager.endChain(state)
} }
} }
fun Job.enableRemoveOnCompletion(state: T) {
invokeOnCompletion {
launchSafelyWithoutExceptions {
statesJobsMutex.withLock {
if (this@enableRemoveOnCompletion === statesJobs[state]) {
statesJobs.remove(state)
}
}
}
}
}
statesManager.onStartChain.subscribeSafelyWithoutExceptions(this) { statesManager.onStartChain.subscribeSafelyWithoutExceptions(this) {
launch { statePerformer(it) } statesJobsMutex.withLock {
runCatchingSafely { statesJobs.remove(it) ?.cancel() }
statesJobs[it] = launch { statePerformer(it) }.apply { enableRemoveOnCompletion(it) }
}
}
statesManager.onEndChain.subscribeSafelyWithoutExceptions(this) {
statesJobsMutex.withLock {
runCatchingSafely { statesJobs.remove(it) ?.cancel() }
}
updatesFlows.remove(it.context)
} }
statesManager.onChainStateUpdated.subscribeSafelyWithoutExceptions(this) { (old, new) -> statesManager.onChainStateUpdated.subscribeSafelyWithoutExceptions(this) { (old, new) ->
statesJobsMutex.withLock {
runCatchingSafely { statesJobs.remove(old) ?.cancel() }
runCatchingSafely { statesJobs.remove(new) ?.cancel() }
statesJobs[new] = launch { statePerformer(new) }.apply { enableRemoveOnCompletion(new) }
}
if (old.context != new.context) { if (old.context != new.context) {
updatesFlows.remove(old.context) updatesFlows.remove(old.context)
} }
launch { statePerformer(new) }
}
statesManager.onEndChain.subscribeSafelyWithoutExceptions(this) {
updatesFlows.remove(it.context)
} }
statesManager.getActiveStates().forEach { statesManager.getActiveStates().forEach {
launch { statePerformer(it) } statesJobsMutex.withLock {
runCatchingSafely { statesJobs.remove(it) ?.cancel() }
statesJobs[it] = launch { statePerformer(it) }.apply { enableRemoveOnCompletion(it) }
}
} }
} }
/** /**

View File

@@ -1,5 +1,7 @@
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.micro_utils.coroutines.launchSafely
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
@@ -29,15 +31,18 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
) )
launch { launch {
launch { launchSafelyWithoutExceptions {
for (update in updatesChannel) { for (update in updatesChannel) {
when (val data = update.data) { val data = update.data
is PossiblyMediaGroupMessage<*> -> mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate) when {
data is PossiblyMediaGroupMessage<*> && data.mediaGroupId != null -> {
mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate)
}
else -> output(update) else -> output(update)
} }
} }
} }
launch { launchSafelyWithoutExceptions {
for ((_, mediaGroup) in mediaGroupAccumulatedChannel) { for ((_, mediaGroup) in mediaGroupAccumulatedChannel) {
mediaGroup.convertWithMediaGroupUpdates().forEach { mediaGroup.convertWithMediaGroupUpdates().forEach {
output(it) output(it)

View File

@@ -41,10 +41,9 @@ fun Route.includeWebhookHandlingInRoute(
post { post {
try { try {
runCatchingSafely { runCatchingSafely {
val asJson = nonstrictJsonFormat.parseToJsonElement(call.receiveText()) val update = nonstrictJsonFormat.decodeFromString(
val update = nonstrictJsonFormat.decodeFromJsonElement(
UpdateDeserializationStrategy, UpdateDeserializationStrategy,
asJson call.receiveText()
) )
transformer(update) transformer(update)
}.onSuccess { }.onSuccess {