1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-09-03 07:09:23 +00:00

small improvements in long polling and behaviour buildr

This commit is contained in:
2025-06-15 11:38:17 +06:00
parent d19e6ad4e0
commit 429fc5d2f9
13 changed files with 75 additions and 49 deletions

View File

@@ -10,7 +10,8 @@
* `Ktor`: `3.1.1` -> `3.1.3`
* `MicroUtils`: `0.25.3` -> `0.25.7`
* `Core`:
* **BREAKING CHANGE** `RequestsExecutor` got property `RequestsExecutor.Log: KSLog?`
* **POTENTIALLY BREAKING CHANGE** Long polling has been reworked a bit
* **BREAKING CHANGE** `RequestsExecutor` got property `RequestsExecutor.Log: KSLog`
* `BehaviourContext`:
* **BREAKING CHANGE** All triggers and waiters become non-suspend functions
* **BREAKING CHANGE** Behaviour of counted extensions (commands, data callback queries, etc.) has been changed a bit: now each one will

View File

@@ -38,9 +38,9 @@ if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != n
// temporal crutch until legacy tests will be stabled or legacy target will be removed
allprojects {
repositories {
maven { url "https://nexus.inmo.dev/repository/maven-releases/" }
mavenCentral()
google()
// maven { url "https://nexus.inmo.dev/repository/maven-releases/" }
mavenLocal()
}
if (it != rootProject.findProject("docs")) {

View File

@@ -217,7 +217,7 @@ fun <T, BC : BehaviourContext> BC.launchInNewSubContext(
updatesUpstreamFlow = updatesUpstreamFlow,
subcontextInitialAction = subcontextInitialAction
).apply {
this@apply.launchLoggingDropExceptions(logger = Log ?: KSLog) {
this@apply.launchLoggingDropExceptions(logger = Log) {
behaviourContextReceiver()
}
}.coroutineContext.job

View File

@@ -40,7 +40,7 @@ class CombinedSubcontextInitialAction(
runCatching {
invoke(update)
}.onFailure {
(Log ?: logger).error(it) {
Log.error(it) {
"Unable to execute $subaction for update $update. Will try on next round"
}
}.onSuccess {
@@ -50,7 +50,7 @@ class CombinedSubcontextInitialAction(
}
leftSubActions.removeAll(successSubActions)
if (successSubActions.isEmpty()) {
(Log ?: logger).error {
Log.error {
"Some SubActions have been unable to complete successfully:${leftSubActions.joinToString("\n") { it.toString() }}"
}
break

View File

@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.bot
import dev.inmo.kslog.common.KSLog
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import io.ktor.utils.io.core.Closeable
/**
@@ -12,8 +13,8 @@ import io.ktor.utils.io.core.Closeable
* @see dev.inmo.tgbotapi.bot.Ktor.KtorRequestsExecutor
*/
interface RequestsExecutor : Closeable {
val Log: KSLog?
get() = null
val Log: KSLog
get() = DefaultKTgBotAPIKSLog
/**
* Unsafe execution of incoming [request]. Can throw almost any exception. So, it is better to use
* something like [dev.inmo.tgbotapi.extensions.utils.shortcuts.executeAsync] or

View File

@@ -29,7 +29,7 @@ expect class KtorRequestsExecutor internal constructor(
logger: KSLog,
diff: Unit // just a diff property to know where constructor and where calling function with defaults
) : BaseRequestsExecutor {
override val Log: KSLog?
override val Log: KSLog
override suspend fun <T : Any> execute(request: Request<T>): T
override fun close()
}

View File

@@ -30,7 +30,7 @@ class DefaultKtorRequestsExecutor internal constructor(
private val logger: KSLog,
diff: Unit
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
override val Log: KSLog? = logger
override val Log: KSLog = logger
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
if (!excludeDefaultFactories) {
this@DefaultKtorRequestsExecutor.logger.v { "Installing default factories" }

View File

@@ -49,7 +49,7 @@ class MultipleClientKtorRequestsExecutor(
logger: KSLog,
clientFactory: () -> HttpClient,
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
override val Log: KSLog? = logger
override val Log: KSLog = logger
private val requestExecutors = (0 until requestExecutorsCount).map {
DefaultKtorRequestsExecutor(
telegramAPIUrlsKeeper,

View File

@@ -6,6 +6,7 @@ import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import kotlinx.coroutines.*
import kotlin.js.JsName
@@ -30,8 +31,8 @@ class SimpleMultiServerRequestsExecutor(
bots.forEach(TelegramBot::close)
}
) : RequestsExecutor {
override val Log: KSLog?
get() = bots.firstNotNullOfOrNull { it.Log }
override val Log: KSLog
get() = bots.firstNotNullOfOrNull { it.Log } ?: DefaultKTgBotAPIKSLog
override suspend fun <T : Any> execute(request: Request<T>): T {
var currentBot = bots.botSelector(-1, null)
while (currentCoroutineContext().isActive) {

View File

@@ -3609,20 +3609,21 @@ public final class dev/inmo/tgbotapi/extensions/utils/updates/retrieving/LongPol
}
public final class dev/inmo/tgbotapi/extensions/utils/updates/retrieving/MediaGroupsIncluderKt {
public static final fun updateHandlerWithMediaGroupsAdaptation (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function2;
public static final fun updateHandlerWithMediaGroupsAdaptation (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;J)Lkotlin/jvm/functions/Function2;
public static synthetic fun updateHandlerWithMediaGroupsAdaptation$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JILjava/lang/Object;)Lkotlin/jvm/functions/Function2;
public static final fun updateHandlerWithMediaGroupsAdaptation (Lkotlinx/coroutines/CoroutineScope;Ldev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function2;
public static final fun updateHandlerWithMediaGroupsAdaptation (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLdev/inmo/kslog/common/KSLog;)Lkotlin/jvm/functions/Function2;
public static synthetic fun updateHandlerWithMediaGroupsAdaptation$default (Lkotlinx/coroutines/CoroutineScope;Ldev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function2;
public static synthetic fun updateHandlerWithMediaGroupsAdaptation$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLdev/inmo/kslog/common/KSLog;ILjava/lang/Object;)Lkotlin/jvm/functions/Function2;
}
public final class dev/inmo/tgbotapi/extensions/utils/updates/retrieving/WebhookKt {
public static final fun includeWebhookHandlingInRoute (Lio/ktor/server/routing/Route;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;)V
public static synthetic fun includeWebhookHandlingInRoute$default (Lio/ktor/server/routing/Route;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
public static final fun includeWebhookHandlingInRouteWithFlows (Lio/ktor/server/routing/Route;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function1;)V
public static synthetic fun includeWebhookHandlingInRouteWithFlows$default (Lio/ktor/server/routing/Route;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static final fun setWebhookInfoAndStartListenWebhooks (Ldev/inmo/tgbotapi/bot/RequestsExecutor;ILio/ktor/server/engine/ApplicationEngineFactory;Ldev/inmo/tgbotapi/requests/webhook/SetWebhookRequest;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/updateshandlers/webhook/WebhookPrivateKeyConfig;Lkotlinx/coroutines/CoroutineScope;JLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun setWebhookInfoAndStartListenWebhooks$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;ILio/ktor/server/engine/ApplicationEngineFactory;Ldev/inmo/tgbotapi/requests/webhook/SetWebhookRequest;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/updateshandlers/webhook/WebhookPrivateKeyConfig;Lkotlinx/coroutines/CoroutineScope;JLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun startListenWebhooks (ILio/ktor/server/engine/ApplicationEngineFactory;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/updateshandlers/webhook/WebhookPrivateKeyConfig;Lkotlinx/coroutines/CoroutineScope;JLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lio/ktor/server/engine/EmbeddedServer;
public static synthetic fun startListenWebhooks$default (ILio/ktor/server/engine/ApplicationEngineFactory;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/updateshandlers/webhook/WebhookPrivateKeyConfig;Lkotlinx/coroutines/CoroutineScope;JLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lio/ktor/server/engine/EmbeddedServer;
public static final fun includeWebhookHandlingInRoute (Lio/ktor/server/routing/Route;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLdev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function2;)V
public static synthetic fun includeWebhookHandlingInRoute$default (Lio/ktor/server/routing/Route;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLdev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
public static final fun includeWebhookHandlingInRouteWithFlows (Lio/ktor/server/routing/Route;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLdev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun includeWebhookHandlingInRouteWithFlows$default (Lio/ktor/server/routing/Route;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLdev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static final fun setWebhookInfoAndStartListenWebhooks (Ldev/inmo/tgbotapi/bot/RequestsExecutor;ILio/ktor/server/engine/ApplicationEngineFactory;Ldev/inmo/tgbotapi/requests/webhook/SetWebhookRequest;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/updateshandlers/webhook/WebhookPrivateKeyConfig;Lkotlinx/coroutines/CoroutineScope;JLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ldev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun setWebhookInfoAndStartListenWebhooks$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;ILio/ktor/server/engine/ApplicationEngineFactory;Ldev/inmo/tgbotapi/requests/webhook/SetWebhookRequest;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/updateshandlers/webhook/WebhookPrivateKeyConfig;Lkotlinx/coroutines/CoroutineScope;JLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ldev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun startListenWebhooks (ILio/ktor/server/engine/ApplicationEngineFactory;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/updateshandlers/webhook/WebhookPrivateKeyConfig;Lkotlinx/coroutines/CoroutineScope;JLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ldev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function2;)Lio/ktor/server/engine/EmbeddedServer;
public static synthetic fun startListenWebhooks$default (ILio/ktor/server/engine/ApplicationEngineFactory;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Ldev/inmo/tgbotapi/updateshandlers/webhook/WebhookPrivateKeyConfig;Lkotlinx/coroutines/CoroutineScope;JLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ldev/inmo/kslog/common/KSLog;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lio/ktor/server/engine/EmbeddedServer;
}
public final class dev/inmo/tgbotapi/types/files/PathedFileAsStreamKt {

View File

@@ -14,6 +14,7 @@ import dev.inmo.tgbotapi.types.update.*
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.updateshandlers.*
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import io.ktor.client.plugins.HttpRequestTimeoutException
import io.ktor.utils.io.CancellationException
import kotlinx.coroutines.*
@@ -33,20 +34,20 @@ fun TelegramBot.longPollingFlow(
mediaGroupsDebounceTimeMillis: Long? = 1000L,
): Flow<Update> = channelFlow {
if (autoDisableWebhooks) {
runCatching {
runCatchingLogging(logger = Log) {
execute(DeleteWebhook())
}
}
val contextSafelyExceptionHandler = coroutineContext[ContextSafelyExceptionHandlerKey]
val contextToWork = if (contextSafelyExceptionHandler == null || !autoSkipTimeoutExceptions) {
val contextSafelyExceptionHandler = coroutineContext[ContextSafelyExceptionHandlerKey] ?.handler ?: defaultSafelyExceptionHandler
val contextToWork = if (!autoSkipTimeoutExceptions) {
coroutineContext
} else {
coroutineContext + ContextSafelyExceptionHandler { e ->
if (e is HttpRequestTimeoutException || (e is CommonBotException && e.cause is HttpRequestTimeoutException)) {
return@ContextSafelyExceptionHandler
} else {
contextSafelyExceptionHandler.handler(e)
contextSafelyExceptionHandler(e)
}
}
}
@@ -61,7 +62,8 @@ fun TelegramBot.longPollingFlow(
send(it)
}
},
mediaGroupsDebounceTimeMillis
mediaGroupsDebounceTimeMillis,
logger = Log
);
{ originalUpdates: List<Update> ->
originalUpdates.forEach {

View File

@@ -1,11 +1,14 @@
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.kslog.common.KSLog
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.updateshandlers.UpdateReceiver
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import dev.inmo.tgbotapi.utils.extensions.accumulateByKey
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
@@ -19,7 +22,8 @@ import kotlinx.coroutines.launch
*/
fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
output: UpdateReceiver<Update>,
debounceTimeMillis: Long = 1000L
debounceTimeMillis: Long = 1000L,
logger: KSLog = DefaultKTgBotAPIKSLog
): UpdateReceiver<Update> {
val updatesChannel = Channel<Update>(Channel.UNLIMITED)
val mediaGroupChannel = Channel<Pair<String, BaseMessageUpdate>>(Channel.UNLIMITED)
@@ -29,7 +33,7 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
)
launch {
launchSafelyWithoutExceptions {
launchLoggingDropExceptions(logger = logger) {
for (update in updatesChannel) {
val data = update.data
when {
@@ -40,7 +44,7 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
}
}
}
launchSafelyWithoutExceptions {
launchLoggingDropExceptions(logger = logger) {
for ((_, mediaGroup) in mediaGroupAccumulatedChannel) {
mediaGroup.convertWithMediaGroupUpdates().forEach {
output(it)
@@ -59,5 +63,6 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
* @see UpdateReceiver
*/
fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
logger: KSLog = DefaultKTgBotAPIKSLog,
output: UpdateReceiver<Update>
) = updateHandlerWithMediaGroupsAdaptation(output, 1000L)
) = updateHandlerWithMediaGroupsAdaptation(output, 1000L, logger = logger)

View File

@@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.kslog.common.KSLog
import dev.inmo.micro_utils.coroutines.ExceptionHandler
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.bot.RequestsExecutor
@@ -12,6 +13,7 @@ import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import dev.inmo.tgbotapi.updateshandlers.UpdateReceiver
import dev.inmo.tgbotapi.updateshandlers.UpdatesFilter
import dev.inmo.tgbotapi.updateshandlers.webhook.WebhookPrivateKeyConfig
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import io.ktor.http.*
import io.ktor.server.engine.*
import io.ktor.server.request.*
@@ -40,9 +42,10 @@ fun Route.includeWebhookHandlingInRoute(
scope: CoroutineScope,
exceptionsHandler: ExceptionHandler<Unit>? = null,
mediaGroupsDebounceTimeMillis: Long = 1000L,
logger: KSLog = DefaultKTgBotAPIKSLog,
block: UpdateReceiver<Update>,
) {
val transformer = scope.updateHandlerWithMediaGroupsAdaptation(block, mediaGroupsDebounceTimeMillis)
val transformer = scope.updateHandlerWithMediaGroupsAdaptation(block, mediaGroupsDebounceTimeMillis, logger = logger)
post {
try {
runCatchingSafely {
@@ -71,11 +74,13 @@ fun Route.includeWebhookHandlingInRouteWithFlows(
scope: CoroutineScope,
exceptionsHandler: ExceptionHandler<Unit>? = null,
mediaGroupsDebounceTimeMillis: Long = 1000L,
logger: KSLog = DefaultKTgBotAPIKSLog,
block: FlowsUpdatesFilter.() -> Unit,
) = includeWebhookHandlingInRoute(
scope,
exceptionsHandler,
mediaGroupsDebounceTimeMillis,
logger,
flowsUpdatesFilter(block = block).asUpdateReceiver
)
@@ -105,6 +110,7 @@ fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configurati
mediaGroupsDebounceTimeMillis: Long = 1000L,
additionalApplicationEnvironmentConfigurator: ApplicationEnvironmentBuilder.() -> Unit = {},
additionalEngineConfigurator: TConfiguration.() -> Unit = {},
logger: KSLog = DefaultKTgBotAPIKSLog,
block: UpdateReceiver<Update>,
): EmbeddedServer<TEngine, TConfiguration> =
embeddedServer(
@@ -134,12 +140,19 @@ fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configurati
routing {
listenRoute?.also {
createRouteFromPath(it).includeWebhookHandlingInRoute(
scope,
exceptionsHandler,
mediaGroupsDebounceTimeMillis,
block
scope = scope,
exceptionsHandler = exceptionsHandler,
mediaGroupsDebounceTimeMillis = mediaGroupsDebounceTimeMillis,
logger = logger,
block = block
)
} ?: includeWebhookHandlingInRoute(scope, exceptionsHandler, mediaGroupsDebounceTimeMillis, block)
} ?: includeWebhookHandlingInRoute(
scope = scope,
exceptionsHandler = exceptionsHandler,
mediaGroupsDebounceTimeMillis = mediaGroupsDebounceTimeMillis,
logger = logger,
block = block
)
}
}
).also {
@@ -173,21 +186,23 @@ suspend fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Con
mediaGroupsDebounceTimeMillis: Long = 1000L,
additionalApplicationEnvironmentConfigurator: ApplicationEnvironmentBuilder.() -> Unit = {},
additionalEngineConfigurator: TConfiguration.() -> Unit = {},
logger: KSLog = Log,
block: UpdateReceiver<Update>,
): EmbeddedServer<TEngine, TConfiguration> = try {
execute(setWebhookRequest)
startListenWebhooks(
listenPort,
engineFactory,
exceptionsHandler,
listenHost,
listenRoute,
privateKeyConfig,
scope,
mediaGroupsDebounceTimeMillis,
additionalApplicationEnvironmentConfigurator,
additionalEngineConfigurator,
block
listenPort = listenPort,
engineFactory = engineFactory,
exceptionsHandler = exceptionsHandler,
listenHost = listenHost,
listenRoute = listenRoute,
privateKeyConfig = privateKeyConfig,
scope = scope,
mediaGroupsDebounceTimeMillis = mediaGroupsDebounceTimeMillis,
additionalApplicationEnvironmentConfigurator = additionalApplicationEnvironmentConfigurator,
additionalEngineConfigurator = additionalEngineConfigurator,
logger = logger,
block = block
)
} catch (e: Exception) {
throw e