Реентерабельность акторов
Вопрос
Метод актора проверяет кеш, при промахе делает await download(url) и пишет результат в кеш. Что может пойти не так?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Ничего: актор заблокирован до конца метода, включая время ожидания
await - Взаимная блокировка: актор ждёт сам себя на
await download(url) - Гонка данных на словаре кеша: два потока пишут в него одновременно
- Во время
awaitактор обслужит другие вызовы, и URL скачается дваждыправильный ответ
Разбор
Акторы в Swift реентерабельны: на каждой точке await актор отпускается и может выполнить другой вызов. Изоляция защищает от гонок данных (одновременного доступа к словарю), но не от логических гонок: два запроса одного URL оба увидят промах. Решение: хранить в кеше не только результат, но и выполняющуюся Task для URL и отдавать её второму вызывающему. И не полагаться на инварианты, проверенные до await. Взаимной блокировки нет как раз благодаря реентерабельности.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.