Воссоздать задание после завершения другого задания

#kotlin #jobs #coroutine

#kotlin #Вакансии #сопрограмма

Вопрос:

У меня следующая ситуация: job1 и job2 отправляются на сервер одновременно, и оба они вернулись со статусом 401 , что означает, что срок действия моего доступа к токену истек, и мне нужно выполнить обновление. Я запускаю job3, который вернул новый токен. В этом случае я должен воссоздать job1 и job2 с новым токеном по запросу и запустить их. У меня есть JobDispatcher, но, похоже, это не помогает мне в ситуации. Вот оно :

 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 вызывается перед запуском job3, и когда результат успешен, вызывается метод resume . Проблема в том, что job1 и job2 теперь завершены, и теперь я должен их воссоздать. Есть ли какая-либо возможность клонировать задание и поместить его в очередь?

Мой вопрос: какое лучшее решение для решения этой проблемы? Я немного растерялся при работе с сопрограммами. Мой код намного сложнее, чем я описал здесь, мне нужны только некоторые рекомендации для этой ситуации, как с этим справиться. Как взаимодействовать между сопрограммами?

Любая идея приветствуется. Спасибо!

Ответ №1:

Я бы заставил job1 и job2 извлекать токен доступа в начале самих себя (извлекать токен доступа из redis или чего-то еще). И затем, если токен доступа истекает, запустите job3 для обновления токена доступа, а затем возобновите все задания. Я не знаю, на что похожи ваши job worker и job dispatcher, но многие реализации в мире с открытым исходным кодом имеют возможность задерживать и повторять неудачное задание. Если у вашего нет такой возможности, вам придется воссоздавать задания, но не нужно беспокоиться о маркере доступа, поскольку он будет извлечен в начале задания.

КОРОЧЕ ГОВОРЯ: не вводите жестко маркер доступа в исходный код. Не кодируйте токен доступа в данных задания. Просто извлеките необходимый токен доступа, когда это необходимо.

Комментарии:

1. Когда задание 3 завершено, токен сохраняется в локальном хранилище. Из локального хранилища job1 и job2 принимают его при создании запроса. Мой вопрос в том, как наладить связь между сопрограммами; job1 и job2 не знают, когда job3 завершено.

2. Если задание 3 будет завершено за короткое время, просто задержите задание 1 и задание 2 еще на несколько секунд. Если нет, просто используйте другую сопрограмму, чтобы периодически проверять ее.

3. Поскольку вы сохраняете токен в локальном хранилище, вы также можете сохранить время последнего обновления токена и время сбоя задания в локальном хранилище. Сравните эти две временные метки, и вы узнаете, обновлен ли токен доступа или истек.

4. Я не думаю, что это хорошая идея. Я назвал здесь job1 и job2, но в моем коде у меня 9 заданий, все они завершаются кодом 401. Должен быть способ повторить их, после чего задание 3 будет завершено.

5. Я использовал этот метод для обработки многих заданий, по нескольку в секунду. Почему это не очень хорошая идея? Хорошо, есть другой способ, если вы можете узнать, как долго истекает токен доступа, вы можете обновить его заранее.