From 0cc0510876b9ce496ae29952c39b628bc39f62e3 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 6 Nov 2023 19:18:19 +0600 Subject: [PATCH] add retryOnPostFailureTimes --- .../kotlin/sending/PostPublisher.kt | 19 ++++++++----- .../src/commonMain/kotlin/Selector.kt | 5 ++++ sample/config.json | 4 ++- triggers/command/src/jvmMain/kotlin/Plugin.kt | 2 +- .../src/jvmMain/kotlin/Plugin.kt | 27 ++++++++++++++----- 5 files changed, 43 insertions(+), 14 deletions(-) diff --git a/posts/src/commonMain/kotlin/sending/PostPublisher.kt b/posts/src/commonMain/kotlin/sending/PostPublisher.kt index 3d3d736..9189519 100644 --- a/posts/src/commonMain/kotlin/sending/PostPublisher.kt +++ b/posts/src/commonMain/kotlin/sending/PostPublisher.kt @@ -11,7 +11,6 @@ import dev.inmo.tgbotapi.extensions.api.send.copyMessage import dev.inmo.tgbotapi.extensions.api.send.send import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.message.content.MediaGroupContent import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent class PostPublisher( @@ -21,10 +20,10 @@ class PostPublisher( private val targetChatIds: List, private val deleteAfterPosting: Boolean = true ) { - suspend fun publish(postId: PostId) { + suspend fun publish(postId: PostId): Boolean { val messagesInfo = postsRepo.getById(postId) ?: let { logger.w { "Unable to get post with id $postId for publishing" } - return + return false } val sortedMessagesContents = messagesInfo.content.groupBy { it.group }.flatMap { (group, list) -> if (group == null) { @@ -35,6 +34,7 @@ class PostPublisher( listOf(list.first().order to list) } }.sortedBy { it.first } + var haveSentMessages = false sortedMessagesContents.forEach { (_, contents) -> contents.singleOrNull() ?.also { @@ -44,13 +44,16 @@ class PostPublisher( }.onFailure { _ -> runCatching { bot.forwardMessage( - it.chatId, - targetChatId, - it.messageId + fromChatId = it.chatId, + toChatId = cachingChatId, + messageId = it.messageId ) }.onSuccess { bot.copyMessage(targetChatId, it) + haveSentMessages = true } + }.onSuccess { + haveSentMessages = true } } return@forEach @@ -61,12 +64,14 @@ class PostPublisher( forwardedMessage.withContentOrNull() ?: null.also { _ -> targetChatIds.forEach { targetChatId -> bot.copyMessage(targetChatId, forwardedMessage) + haveSentMessages = true } } } resultContents.singleOrNull() ?.also { targetChatIds.forEach { targetChatId -> bot.copyMessage(targetChatId, it) + haveSentMessages = true } return@forEach } ?: resultContents.chunked(mediaCountInMediaGroup.last).forEach { @@ -75,6 +80,7 @@ class PostPublisher( targetChatId, it.map { it.content.toMediaGroupMemberTelegramMedia() } ) + haveSentMessages = true } } } @@ -83,5 +89,6 @@ class PostPublisher( postsRepo.deleteById(postId) } + return haveSentMessages } } diff --git a/ratings/selector/src/commonMain/kotlin/Selector.kt b/ratings/selector/src/commonMain/kotlin/Selector.kt index 4d670b2..4c46ceb 100644 --- a/ratings/selector/src/commonMain/kotlin/Selector.kt +++ b/ratings/selector/src/commonMain/kotlin/Selector.kt @@ -5,4 +5,9 @@ import dev.inmo.plaguposter.posts.models.PostId interface Selector { suspend fun take(n: Int = 1, now: DateTime = DateTime.now(), exclude: List = emptyList()): List + suspend fun takeOneOrNull(now: DateTime = DateTime.now(), exclude: List = emptyList()): PostId? = take( + n = 1, + now = now, + exclude = exclude + ).firstOrNull() } diff --git a/sample/config.json b/sample/config.json index 87a7955..ccc880e 100644 --- a/sample/config.json +++ b/sample/config.json @@ -65,7 +65,9 @@ ] }, "timer_trigger": { - "krontab": "0 30 2/4 * *" + "krontab": "0 30 2/4 * *", + "retryOnPostFailureTimes": 0, + "_note": "retryOnPostFailureTimes will retry to publish one or several posts if posting has been failed" }, "panel": { "textPrefix": "Post management:", diff --git a/triggers/command/src/jvmMain/kotlin/Plugin.kt b/triggers/command/src/jvmMain/kotlin/Plugin.kt index a789fd7..6a31c1f 100644 --- a/triggers/command/src/jvmMain/kotlin/Plugin.kt +++ b/triggers/command/src/jvmMain/kotlin/Plugin.kt @@ -77,7 +77,7 @@ object Plugin : Plugin { return@onCommand } - } ?: selector ?.take(1) ?.firstOrNull() + } ?: selector ?.takeOneOrNull() if (postId == null) { reply( it, diff --git a/triggers/selector_with_timer/src/jvmMain/kotlin/Plugin.kt b/triggers/selector_with_timer/src/jvmMain/kotlin/Plugin.kt index 84f463b..5163317 100644 --- a/triggers/selector_with_timer/src/jvmMain/kotlin/Plugin.kt +++ b/triggers/selector_with_timer/src/jvmMain/kotlin/Plugin.kt @@ -51,7 +51,8 @@ object Plugin : Plugin { internal data class Config( @SerialName("krontab") val krontabTemplate: KrontabTemplate, - val dateTimeFormat: String = "HH:mm:ss, dd.MM.yyyy" + val dateTimeFormat: String = "HH:mm:ss, dd.MM.yyyy", + val retryOnPostFailureTimes: Int = 0 ) { @Transient val krontab by lazy { @@ -88,13 +89,27 @@ object Plugin : Plugin { } val krontab = koin.get().krontab + val retryOnPostFailureTimes = koin.get().retryOnPostFailureTimes val dateTimeFormat = koin.get().format krontab.asFlowWithDelays().subscribeSafelyWithoutExceptions(this) { dateTime -> - selector.take(now = dateTime).forEach { postId -> - if (filters.all { it.check(postId, dateTime) }) { - publisher.publish(postId) + var leftRetries = retryOnPostFailureTimes + do { + val success = runCatching { + selector.takeOneOrNull(now = dateTime) ?.let { postId -> + if (filters.all { it.check(postId, dateTime) }) { + publisher.publish(postId) + } else { + false + } + } ?: false + }.getOrElse { + false } - } + if (success) { + break; + } + leftRetries--; + } while (leftRetries > 0) } suspend fun buildPage(pagination: Pagination = FirstPagePagination(size = pageCallbackDataQuerySize)): InlineKeyboardMarkup { @@ -113,7 +128,7 @@ object Plugin : Plugin { val selected = mutableListOf() krontab.asFlowWithoutDelays().take(pagination.lastIndexExclusive).collectIndexed { i, dateTime -> - val postId = selector.take(now = dateTime, exclude = selected).firstOrNull() ?.also { postId -> + val postId = selector.takeOneOrNull(now = dateTime, exclude = selected) ?.also { postId -> if (filters.all { it.check(postId, dateTime) }) { selected.add(postId) } else {