Created
March 31, 2023 07:20
-
-
Save xmaihh/a3314957bb613485164c6ed91f4b9d08 to your computer and use it in GitHub Desktop.
Kotlin执行指定的异步任务,并在规定时间内尝试重发直到满足条件或者超时
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 执行指定的异步任务,并在规定时间内尝试重发直到满足条件或者超时。 | |
* | |
* @param timeout 超时时间,单位为毫秒。 | |
* @param retryCount 最多重发次数。 | |
* @param delayTime 重发间隔时间,单位为毫秒。 | |
* @param shouldRetryPredicate 判断是否需要进行重发的函数。该函数返回true时进行重发。 | |
* @param block 异步任务的执行体。该执行体需要支持取消操作。 | |
* @return 异步任务的返回结果,如果超时或者达到最大重发次数仍未获取到期望结果,则返回null。 | |
*/ | |
private suspend fun <T> withRetryAndWaitForResult( | |
timeout: Long, | |
retryCount: Int, | |
delayTime: Long = 0L, | |
shouldRetryPredicate: suspend (result: T?) -> Boolean, | |
block: suspend () -> T | |
): T? = supervisorScope { | |
var retry = 0 | |
var result: T? = null | |
while (shouldRetry) { | |
// 设置超时时间 | |
val timeoutResult = withTimeoutOrNull(timeout) { | |
// 执行异步任务 | |
block() | |
} | |
// 判断是否超时 | |
if (timeoutResult == null) { | |
retry++ | |
//判断是否达到最大重发次数 | |
if (retry >= retryCount) { | |
break | |
} | |
//等待一段时间后重发 | |
if (delayTime > 0) { | |
delay(delayTime) | |
} | |
} else { | |
result = timeoutResult | |
// 判断是否需要进行重发 | |
if (!shouldRetryPredicate(result)) { | |
break // 不需要重发,直接返回结果 | |
} | |
//如果不满足停止条件,则继续重发 | |
retry++ | |
if (retry >= retryCount) { | |
break | |
} | |
//等待一段时间后重发 | |
if (delayTime > 0) { | |
delay(delayTime) | |
} | |
} | |
} | |
result | |
} | |
fun main() = runBlocking { | |
var shouldRetry = true // 外部变量,用于控制是否重发 | |
// 执行异步任务,并设置超时时间为5秒。 | |
val result = withTimeoutAndConditionalRetryAndWaitForResult<String>(timeout = 1500, retryCount = 3, delayTime = 1000, { stopCondition(it) }) { | |
if (shouldRetry) { // 检查外部变量是否改变 | |
doTask() | |
} else { | |
null // 如果外部变量已经改变,则直接返回null | |
} | |
} | |
// 输出结果 | |
println(result ?: "Timeout or should not retry.") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment