#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. Я использовал этот метод для обработки многих заданий, по нескольку в секунду. Почему это не очень хорошая идея? Хорошо, есть другой способ, если вы можете узнать, как долго истекает токен доступа, вы можете обновить его заранее.