Материал проходит вычитку — возможны неточности.
Урок 15 из 118

Тонкости weighted †

На ревью генерации превью Аня показала две тонкости: TryAcquire не обгонял ждущих и сразу возвращал false, а Release паниковал при переборе бюджета. Миша записал обе в договор стадии.

Главная мысль

у взвешенного семафора два неочевидных поведения: TryAcquire не проскакивает очередь ждущих — при их наличии сразу возвращает false, а Release паникует, если вернуть больше бюджета, чем было занято.

TryAcquire и очередь

if sem.TryAcquire(10) {
    defer sem.Release(10)
    makePreview()
} else {
    fallback()
}

TryAcquire — неблокирующая попытка: метод никогда не ждёт и в очередь не встаёт. Неочевидное: если в очереди уже стоят горутины, ждущие Acquire, TryAcquire не проскакивает мимо них — он немедленно возвращает false, даже если бюджета для запроса хватает. Казалось бы, «попробовать» должно быть дешевле, но попытка не имеет права опередить ждущих — иначе «пробующие» голодали бы «ждущих». Получил false — делай fallback.

Release паникует при переборе

sem.Release(10) // panic: semaphore: released more than held

Release требует ровно то, что было занято. Вернуть больше бюджета — паника, и это хорошо: перебор бюджета — симптом рассогласования Acquire/Release, который иначе тихо разъел бы лимит. Симметрию держит тот же приём, что и раньше: defer sem.Release(вес) сразу после успешного Acquire.

Что это значит на практике

Обе тонкости — про дисциплину. Мгновенный false у TryAcquire означает: «попробовал — не прошло, делай fallback», но обойти очередь ждущих нельзя. Паника Release означает: несовпадение весов — баг, который должен падать сразу, а не копиться. В продакшене это пара «Acquire(ctx, n) + defer Release(n)» и ничего больше.

В следующем уроке

Вы узнаете:

  • почему паника при переборе лучше молчаливого варианта
  • как TryAcquire реализует backpressure
Задание · вопросы

Проверьте себя

Вопрос 1 из 3

sem.Release(1) при пустом бюджете (ничего не занято). Что произойдёт?

Вопрос 2 из 3

В очереди стоит горутина, но свободный бюджет есть. Что вернёт TryAcquire?

Вопрос 3 из 3

Вес задачи в Acquire и Release вычисляется заново дважды. Чем грозит?

Итоги

TryAcquire неблокирующий: false при нехватке бюджета или при наличии ждущих; Release паникует при переборе. Обе тонкости держат лимит честным, а баги — громкими.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки