Как стать автором
Обновить

Комментарии 1

Ваши коллеги по цеху придумали другое решение, которое является более самостоятельной и переиспользуемой версией "флага защиты от рекурсии" - реализация интерфейсаBitrix\HumanResources\Contract\Service\SemaphoreService. По сути, этот сервис предоставляет средства консультативной блокировки, который держит все блокировки в памяти.

Использование выглядит примерно так:

<?php

use Bitrix\HumanResources\Service\Container;

function handleUpdate(): void {
  $semaphoreService = Container::getSemaphoreService();
  if ($semaphoreService->isLocked('UNIQUE_LOCK_NAME')) {
    return;
  }

  $semaphoreService->lock('UNIQUE_LOCK_NAME');
  // ... do recursive stuff ...
  $semaphoreService->unlock('UNIQUE_LOCK_NAME');
}

Помимо того, что с помощью SemaphoreService можно гораздо явнее обозначить защиту от рекурсии, вы также избавляете себя от нескольких головных болей:

  • Решение единообразное и может быть переиспользовано в нескольких проектах, в отличие от необходимости каждый раз внедрять статическое поле в класс, который может столкнуться с проблемами рекурсии;

  • Нет необходимости предоставлять публичное API внутри вашего класса. Те разработчики, которые хотят управлять этим поведением извне, будут использовать SemaphoreService, а не API вашего класса; вы, таким образом, снимаете с себя (а именно, со своего класса) ответственность, всё "неожиданное" поведение оказывается виной того, кто нарушил инкапсуляцию вашего обработчика.

Странно, что подобного сервиса всё ещё нет в главном модуле.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий