orbit.client.execution.AddressableDeactivator.kt Maven / Gradle / Ivy
/*
Copyright (C) 2015 - 2020 Electronic Arts Inc. All rights reserved.
This file is part of the Orbit Project .
See license in LICENSE.
*/
package orbit.client.execution
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.flatMapMerge
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.toList
import mu.KotlinLogging
import orbit.util.di.ExternallyConfigured
import orbit.util.time.highResolutionTicker
typealias Deactivator = suspend (handle: Deactivatable) -> Unit
@OptIn(FlowPreview::class)
abstract class AddressableDeactivator() {
protected val logger = KotlinLogging.logger { }
abstract suspend fun deactivate(addressables: List, deactivate: Deactivator)
@OptIn(ExperimentalCoroutinesApi::class)
protected suspend fun deactivateItems(
addressables: List,
concurrency: Int,
deactivationsPerSecond: Long,
deactivate: Deactivator
) {
val ticker = highResolutionTicker(deactivationsPerSecond.toDouble())
addressables.asFlow().onEach { ticker.receive() }
.flatMapMerge(concurrency) { a ->
flow { emit(deactivate(a)) }
}.toList()
}
class Concurrent(private val config: Config) : AddressableDeactivator() {
data class Config(val concurrentDeactivations: Int) :
ExternallyConfigured {
override val instanceType: Class = Concurrent::class.java
}
override suspend fun deactivate(addressables: List, deactivate: Deactivator) {
deactivateItems(addressables, config.concurrentDeactivations, Long.MAX_VALUE, deactivate)
}
}
class RateLimited(private val config: Config) : AddressableDeactivator() {
data class Config(val deactivationsPerSecond: Long) :
ExternallyConfigured {
override val instanceType: Class = RateLimited::class.java
}
override suspend fun deactivate(addressables: List, deactivate: Deactivator) {
deactivateItems(addressables, Int.MAX_VALUE, config.deactivationsPerSecond, deactivate)
}
}
class TimeSpan(private val config: Config) : AddressableDeactivator() {
data class Config(val deactivationTimeMilliseconds: Long) :
ExternallyConfigured {
override val instanceType: Class = TimeSpan::class.java
}
override suspend fun deactivate(addressables: List, deactivate: Deactivator) {
val deactivationsPerSecond = addressables.count() * 1000 / config.deactivationTimeMilliseconds
deactivateItems(addressables, Int.MAX_VALUE, deactivationsPerSecond, deactivate)
}
}
class Instant : AddressableDeactivator() {
class Config : ExternallyConfigured {
override val instanceType: Class = Instant::class.java
}
override suspend fun deactivate(addressables: List, deactivate: Deactivator) {
deactivateItems(addressables, Int.MAX_VALUE, Long.MAX_VALUE, deactivate)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy