【问题标题】:Kotlin Coroutines: suspending subsequent access token renewal requestsKotlin Coroutines:暂停后续访问令牌更新请求
【发布时间】:2019-09-12 12:08:40
【问题描述】:

我有一个应用程序,它通过后端进行身份验证并接收一个长期刷新令牌和短期访问令牌。我们使用访问令牌来授权我们的请求,并且每次它过期时,我们都会在使用新令牌重试 API 调用之前触发令牌更新(使用刷新令牌)。很标准的东西。

可以同时(异步)触发多个网络调用,但如果它们都有无效的访问令牌,我们只希望第一个通过并刷新令牌,而后续调用等待第一个调用完成之前继续。目前,我们是这样实现的:

private var renewingDeferred: Deferred<Unit>? = null

suspend fun renewTokens() {
    coroutineScope {
        if (renewingDeferred == null) {
            renewingDeferred = async {
                try {
                    tokens = tokensApi.renew().await()
                } finally {
                    renewingDeferred = null
                }
            }
        } else {
            renewingDeferred?.await()
        }
    }
}

这个想法是每个具有无效访问令牌的请求都将调用renewTokens(),然后使用新的标头重试。 renewTokens() 的调用者不应该关心它是实际更新还是只是等待先前的更新完成,只要它知道一旦函数返回(不再暂停)令牌就会更新。据我所知,它运行良好,但我不完全确定代码,特别是 finally 块的 renewingDeferred = null 部分。

例如,假设请求 A 开始更新,请求 B 被触发并开始等待请求 A,然后 A 完成,将 renewingDeferred 设置为 null,但将该值设置为 null 会以某种方式影响请求 B 的等待状态?

另外,如果调用 API 时抛出异常怎么办?我没有 catch 块,有点假设 await()ing 在一个 deferred 上会以某种方式重新抛出,但协程中的异常处理并不是我的强项。很想在这方面得到一些建议。

另外,如果有人对如何以不同的方式解决这个问题有一个大致的了解,欢迎提出所有建议!

【问题讨论】:

    标签: kotlin kotlin-coroutines


    【解决方案1】:

    您可以使用 Mutex 解决此问题。 为协程锁定创建一个属性,在调用renewToken时锁定Mutex,直到token被更新。

    【讨论】:

      猜你喜欢
      • 2020-06-01
      • 2019-12-03
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多