Новое в Symfony 5.2: Компонент семафор

Symfony представила компонент Lock в Symfony 3.4, чтобы предоставить механизм для предоставления монопольного доступа к общему ресурсу. В некоторых случаях недостаточно предоставить доступ к одному процессу, и вам нужно разрешить доступ нескольким параллельным процессам.

Согласно определению Википедии, семафор — это переменный или абстрактный тип данных, используемый для управления доступом к общему ресурсу множеством процессов в параллельной системе, такой как многозадачная операционная система. Вообще говоря, семафор позволяет процессу N получить доступ к ресурсу, а блокировка – это семафор, где N = 1.

В Symfony 5.2 представляем новый компонент Semaphore. Вместо использования простой переменной компонент Semaphore использует хранилище (например, сервер Redis). Сначала создайте хранилище:

use Symfony\Component\Semaphore\SemaphoreFactory;
use Symfony\Component\Semaphore\Store\RedisStore;

$redis = new Redis();
$redis->connect('172.17.0.2');
$store = new RedisStore($redis);
$factory = new SemaphoreFactory($store);

Затем используйте эту фабрику для фактического создания семафора:

// ...
$semaphore = $factory->createSemaphore('pdf-invoice-generation', 2);
if ($semaphore->acquire()) {
    // The resource "pdf-invoice-generation" is locked.
    // You can compute and generate invoice safely here.

    $semaphore->release();
}

Учитывая однопоточную природу PHP, чтобы полностью использовать семафор в параллельном процессе, вы должны запустить N worker. В каждом работнике вы ищете работу. Если вы получили работу, попробуйте обзавестись семафором. Если вы его приобретете, обработайте задание; в противном случае попробуйте найти другую работу.

Прочтите документацию по компоненту Semaphore, чтобы узнать о нем все.