
com.github.insanusmokrassar.AutoPostTelegramBot.utils.extensions.BroadcastChannel.kt Maven / Gradle / Ivy
package com.github.insanusmokrassar.AutoPostTelegramBot.utils.extensions
import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.channels.BroadcastChannel
import kotlinx.coroutines.experimental.channels.ReceiveChannel
import java.util.concurrent.TimeUnit
fun BroadcastChannel.subscribeChecking(
throwableHandler: (Throwable) -> Boolean = {
it.printStackTrace()
true
},
by: suspend (T) -> Boolean
): ReceiveChannel {
return openSubscription().also {
launch {
while (isActive && !it.isClosedForReceive) {
try {
val received = it.receive()
launch {
try {
if (!by(received)) {
it.cancel()
}
} catch (e: Throwable) {
if (!throwableHandler(e)) {
it.cancel()
}
}
}
} catch (e: CancellationException) {
break
}
}
it.cancel()
}
}
}
fun BroadcastChannel.subscribe(
throwableHandler: (Throwable) -> Boolean = {
it.printStackTrace()
true
},
by: suspend (T) -> Unit
): ReceiveChannel {
return subscribeChecking(throwableHandler) {
by(it)
true
}
}
fun ReceiveChannel.debounce(delayMs: Long, awaitedSubscriptions: Int = 256): BroadcastChannel {
val channel = BroadcastChannel(awaitedSubscriptions)
var lastReceived: Pair? = null
var job: Job? = null
launch {
while (isActive && !isClosedForReceive) {
val received = receive()
lastReceived = Pair(System.currentTimeMillis() + delayMs, received)
job ?:let {
job = launch {
try {
var now = System.currentTimeMillis()
while (isActive && lastReceived?.first ?: now >= now) {
delay((lastReceived ?.first ?: now) - now, TimeUnit.MILLISECONDS)
now = System.currentTimeMillis()
}
lastReceived?.second?.also {
channel.send(it)
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
job = null
}
}
}
}
cancel()
}
return channel
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy