net.devslash.PollUntil.kt Maven / Gradle / Ivy
package net.devslash
import kotlinx.coroutines.delay
import java.util.concurrent.atomic.AtomicBoolean
import java.util.logging.Logger
data class PollPredicateCtx(val req: HttpRequest, val resp: HttpResponse, val data: T)
typealias PollPredicate = PollPredicateCtx.() -> Boolean
/**
* PollUntil allows one to set up a DSL context that ensures that a request
* will poll until such a time that the predicate returns true. Due to
* how this request type works, the concurrency is set at 1.
*/
class PollUntil(private val predicate: PollPredicate,
private val clazz: Class,
private val data: T) :
CallDecorator,
ResolvedFullDataAfterHook,
RequestDataSupplier {
private val logger = Logger.getLogger(PollUntil::class.java.simpleName)
private val requestAllowed = AtomicBoolean(true)
private var finished = false
companion object {
inline operator fun invoke(noinline predicate: PollPredicate,
data: T): PollUntil {
return PollUntil(predicate, T::class.java, data)
}
operator fun invoke(predicate: PollPredicate>): PollUntil> {
return PollUntil(predicate, listOf())
}
}
override fun accept(call: Call): Call {
if (call.dataSupplier != null) {
logger.warning("Data supplier set, will be overwritten by `PollUntil`")
}
if (call.concurrency != 1) {
logger.info("Call concurrency was " + call.concurrency + ". Setting to 1")
}
return Call(call.url, call.urlProvider,
1, null, call.headers, call.type, this, call.body, call.onError,
call.beforeHooks, call.afterHooks + this)
}
override suspend fun getDataForRequest(): RequestData? {
while (!requestAllowed.compareAndSet(true, false)) {
delay(50)
}
if (finished) {
return null
}
return ListRequestData(data, clazz)
}
override fun accept(req: HttpRequest, resp: HttpResponse, data: T) {
finished = PollPredicateCtx(req, resp, data).predicate()
requestAllowed.set(true)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy