【问题标题】:Notify jobs when another job finishes当另一个作业完成时通知作业
【发布时间】:2019-09-06 07:16:51
【问题描述】:

在我的应用程序中,所有请求都需要一个令牌作为 http 授权标头,该标头会在一定时间后过期。当从服务器获取具有401 状态代码的作业时,我需要启动作业以刷新令牌。当此作业完成后,我需要通知我的应用程序中的所有作业,因为我不知道其中哪些作业失败(作业已完成但具有 401 http 状态),我必须使用新令牌重试。

如何使用协程做到这一点?

【问题讨论】:

  • 这个问题很不清楚。此外,这听起来像是要求一个完整的设计/设计理念,而不是针对一个重点问题的解决方案,而是邀请讨论而不是明确的答案。
  • @MarkoTopolnik 感谢您的回复。我想你是对的。我在这些问题之前又写了一个:stackoverflow.com/questions/55647810/…也许这些问题一起可以澄清我的问题。
  • 我在服务层有很多类,每个类都向服务器请求某些实体。例如,MessageService 发送从服务器检索所有消息的请求。当它返回 401 http 状态时,AuthenticationService 启动 refreshToken 请求。我找到了一种解决方案,可以在刷新回调时发送一些指示令牌已成功刷新的信息,但是如果从 refreshToken 接收到该信息,这会使每个作业都被重新创建。我是 Coroutine 的新手,我问是否有某种方法可以订阅一份工作,知道它什么时候完成等等。
  • @MarkoTopolnik invokeOnCompletion 是一个解决方案,具有我上面提到的回调。演员,频道可以吗?我不知道如何使用它们。

标签: kotlin jobs kotlin-coroutines


【解决方案1】:

首先,让我们定义令牌的刷新方式:

1) 如果还没有刷新token的请求,就开始一个新的

2) 如果已经有一个,那就等着吧。

在 Kotlin 中可以写成:

  var retrieveToken : Deferred<String>? = null

  suspend fun getToken(refresh: Boolean = false): String {
    if(retrieveToken == null || refresh && !retrieveToken.isActive)
      retrieveToken = async { API.getToken() }
    return retrieveToken.await()
  }

现在重试 API 变得相当简单:

  suspend fun requestAPIAndRetry(api: String) {
     try {
       val token = getToken()
       val result = API.call(api, token)
     } catch(error) {
      // verifiy if it is 401
      val token = getToken(refresh = true)
      var result = API.call(api, token)
    }
 }

现在如果请求开始失败,会发生以下情况:

1) 对getToken(refresh = true) 的第一次调用将启动对 API 的请求并返回该请求。

2) 所有后续调用都将获得与第一次调用相同的延迟,因此所有请求只等待一个令牌更新

3) 如果令牌存在,Deferred 将解析,所有 API 将重试(甚至可能并行)。

【讨论】:

    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 2019-09-02
    • 2016-11-26
    • 2018-12-07
    • 1970-01-01
    • 2022-10-17
    • 2020-02-28
    • 1970-01-01
    相关资源
    最近更新 更多