[Grouple] Selecting the fastest pages server
parent
e51b33c74a
commit
454b24ec88
@ -0,0 +1,40 @@
|
||||
package org.koitharu.kotatsu.parsers.util
|
||||
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
fun Iterable<Job>.cancelAll(cause: CancellationException? = null) {
|
||||
forEach { it.cancel(cause) }
|
||||
}
|
||||
|
||||
suspend fun <T> Iterable<Deferred<T>>.awaitFirst(): T = select<T> {
|
||||
for (async in this@awaitFirst) {
|
||||
async.onAwait { it }
|
||||
}
|
||||
}.also { this@awaitFirst.cancelAll() }
|
||||
|
||||
suspend fun <T> Collection<Deferred<T>>.awaitFirst(condition: (T) -> Boolean): T {
|
||||
var result: Any? = NULL
|
||||
var counter = size
|
||||
while (result === NULL && counter > 0) {
|
||||
val candidate = select<T> {
|
||||
for (async in this@awaitFirst) {
|
||||
async.onAwait { it }
|
||||
}
|
||||
}
|
||||
if (condition(candidate)) {
|
||||
result = candidate
|
||||
}
|
||||
counter--
|
||||
}
|
||||
cancelAll()
|
||||
if (result === NULL) {
|
||||
throw NoSuchElementException()
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return result as T
|
||||
}
|
||||
|
||||
private val NULL = Any()
|
||||
Loading…
Reference in New Issue