Kotlin · 3 / 6

Отмена, ошибки и structured concurrency

Кто владеет работой, кто отменяет соседей и где ловить ошибку

Работа принадлежит области

suspend разрешает приостановку, но не назначает фоновый поток. Дочерняя работа принадлежит своему Job: обычная ошибка ребёнка отменяет родителя и соседей. В supervisorScope сбой ребёнка не отменяет остальных автоматически; обработка ошибки всё равно нужна. Ошибка самого блока supervisorScope отменяет его детей. Kotlin: исключения корутин.

Отмена — кооперативный протокол

CPU-цикл без проверок может продолжать работу после cancel. Вызывайте currentCoroutineContext().ensureActive() в разумных точках. Произвольная suspend-функция не обязана ни приостанавливаться, ни проверять отмену. ensureActive.

import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.ensureActive

suspend fun sum(values: IntArray): Long {
    var total = 0L
    for (value in values) {
        currentCoroutineContext().ensureActive()
        total += value
    }
    return total
}

Выбор диспетчера делает вызывающий код или явно выделенная вычислительная граница.

Не превращайте отмену в ошибку сети

При широком catch (Exception) сначала пробрасывайте CancellationException. CoroutineExceptionHandler наблюдает необработанное исключение, но не возобновляет упавшую корутину. Ошибку async получают через await; в обычной иерархии родитель может отмениться ещё до await. Kotlin: исключения корутин.

Mutex защищает составную операцию и при ожидании не блокирует поток. Он не реентерабелен: повторный lock под уже удерживаемой блокировкой способен навсегда приостановить работу. Потокобезопасность отдельного get/set не делает атомарным read-modify-write. Mutex.

Основа отбора: draft/coroutines.md, draft/M++.md, draft/lifeconding.md.

К вопросам →