🔍 Автор столкнулся с задачей запретить одновременный запуск
async метода и показал, почему ни actor, ни Mutex не подходят. Решение - библиотека TaskGate (AsyncGate и AsyncRecursiveGate): это асинхронный «турникет», который допускает только одну задачу внутрь и при этом безопасно позволяет await внутри секции.❓ Внутреннее состояние - два состояния (.
unlocked и .locked(queue)) и простой NSLock для защиты этих маленьких синхронных обновлений. Первая задача просто «заходит» и оставляет дверь закрытой; последующие регистрируют свою continuation как билет в очередь и «паркуются» без блокировки потока. Когда владелец выходит, он не открывает ворота всем сразу, а передаёт продолжение следующему - handoff, честная FIFO-очередь, никакой толкучки.✔️ Этот подход подход даёт нужную семантику асинхронной взаимной исключённости и решает проблему priority inversion — при поддержке ОС библиотека эскалирует приоритеты ожидающих задач, прокидывая bump по очереди.
❌ Из минусов -
AsyncGate не Sendable и предназначен жить в одном акторе (во избежание ошибок), а вход в тот же gate из той же задачи приведёт к дедлоку - для этого есть AsyncRecursiveGate.