Реализация механизма повторных запросов (Polling) с условиями завершения

Polling должен завершаться при готовом результате, терминальной ошибке, отмене или исчерпании лимита. Цикл с delay не блокирует поток; число попыток и общий срок ожидания нужно ограничить.

Короткий ответ

Что ответить на собеседовании

Polling должен завершаться при готовом результате, терминальной ошибке, отмене или исчерпании лимита. Цикл с delay не блокирует поток; число попыток и общий срок ожидания нужно ограничить.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо разработать логику повторных запросов (polling), включающую условия остановки и возврат полученного результата.

class RepeatedRequestUseCase(
    private val fetchSomethingUseCase: GetSomethingUseCase
) {
    suspend fun invoke(id: String): Result {
        // TODO impl
    }
}

Ответ

Polling должен завершаться при готовом результате, терминальной ошибке, отмене или исчерпании лимита. Цикл с delay не блокирует поток; число попыток и общий срок ожидания нужно ограничить.

Так как поля Result не заданы, условие готовности передаётся явно:

suspend fun <T> poll(
    fetch: suspend () -> T,
    isDone: (T) -> Boolean,
    attempts: Int = 20
): T = withTimeout(60_000) {
    require(attempts > 0)
    repeat(attempts) { index ->
        val result = fetch()
        if (isDone(result)) return@withTimeout result
        if (index < attempts - 1) delay(1_000)
    }
    error("Polling limit reached")
}

Обёртка вызывает fetchSomethingUseCase для нужного id. В примере ошибки запроса пробрасываются; если нужны повторы временных сбоев, задайте их отдельно. CancellationException не поглощайте, а терминальный бизнес-статус не путайте с «ещё обрабатывается».

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее