3

I have the following situation: job1 and job2 go to the server in the same time and both of them came back with status 401, which means that my token access has expired and I need to make a refresh. I start job3 which came back the new token. In this case, I have to recreate the job1 and job2 with the new token on request and start them. I have a jobDispatcher, but it seems that it not help me in situation. Here it is :

class JobDispatcher : CoroutineDispatcher() {
  private val queue: Queue<Runnable> = LinkedList()
  private var isPaused: Boolean = false
  private var lastExecutedBlock: Runnable? = null

  @Synchronized
  override fun dispatch(context: CoroutineContext, block: Runnable) {
    if (isPaused) {
      queue.add(block)
    } else {
      thread {
        lastExecutedBlock = block
        block.run()
      }
    }
  }

  @Synchronized
  fun pause() {
    isPaused = true
    if (lastExecutedBlock != null) {
      queue.add(lastExecutedBlock)
      lastExecutedBlock = null
    }
  }

  @Synchronized
  fun resume() {
    isPaused = false
    runQueue()
  }
}

Pause method is called before job3 to start, and when the result is successful, resume method is called. The problem is that job1 and job2 are now completed and now I should recreate them. Is there any possibility to clone the job, and put it in a queue?

My question is: which is the best solution to solve this? I fell a little lost when working with coroutines. My code is much complicated then I described here, I need just some guidelines for this situation, how to manage it. How to communicate between coroutines?

Any idea is welcome. Thank you!

Gabrielle
  • 4,933
  • 13
  • 62
  • 122

1 Answers1

0

I would make job1 and job2 fetch the access token at the beginning of themselves (fetch the access token from redis or something else). And then if access token expires, start job3 to update the access token, and then resume all the jobs. I don't know how your job worker and job dispatcher are like, but many implementations in the open source world have the ability to delay and retry a failed job. If yours doesn't have this ability, you have to recreate jobs, but no need to worry about the access token, since it will be fetched at the beginning of the job.

IN SHORT: Don't hardcode the access token in source code. Don't encode the access token in the job data. Just fetch the needed access token when it is needed.

duyue
  • 759
  • 5
  • 12
  • When job3 is completed, it saves token in local storage. From local storage job1 and job2 takes it when the request is created. My question is how to make the communication between coroutines; job1 and job2 doesn't know when job3 is completed. – Gabrielle Apr 15 '19 at 08:30
  • If job3 will finished in a short time then just delay job1 and job2 a few more seconds. If not, just use another coroutine to check it periodically. – duyue Apr 15 '19 at 08:33
  • Since you saves token in local storage, you can also save token last updated time and job failed time in local storage. Compare these two timestamp and you'll know whether the access token is updated or expired. – duyue Apr 15 '19 at 08:40
  • I don't think this is a good idea. I named here job1 and job2, but in my code I have 9 jobs, all get completed with 401 code. There must be a way to retry them then job3 is completed. – Gabrielle Apr 15 '19 at 09:02
  • I have used this method to process many jobs, several per second. Why is this not a good idea? OK, there's another way, if you can know how long will the access token go expire, you can update it in advance. – duyue Apr 15 '19 at 09:26