Contributed by
Grégoire Pineau
in #35780.
Symfony introduced the Lock component in Symfony 3.4, to provide a mechanism to grant exclusive access to a shared resource. In some cases, it’s not enough to provide access to a single process and you need to allow access to multiple concurrent processes.
According to the Wikipedia definition, a semaphore is a variable or abstract data type used to control access to a common resource by multiple processes in a concurrent system such as a multitasking operating system. Broadly speaking, a semaphore allows N process to access a resource, and a lock is a semaphore where N = 1.
In Symfony 5.2 we’re introducing a new Semaphore component. Instead of using a simple variable, the Semaphore component uses a store (e.g. a Redis server). First, create the store:
1 2 3 4 5 6 7 | useSymfony\Component\Semaphore\SemaphoreFactory;useSymfony\Component\Semaphore\Store\RedisStore;$redis=newRedis();$redis->connect('172.17.0.2');$store=newRedisStore($redis);$factory=newSemaphoreFactory($store); |
Then, use that factory to actually create a semaphore:
1 2 3 4 5 6 7 8 | // ...$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();} |
Given the single-threaded nature of PHP, to fully use the semaphore in concurrent process you must run N workers. In each worker you look for a job to do. If you get a job, try to acquire a semaphore. If you acquire it, process the job; otherwise, try to find another job.
Read the Semaphore component documentation to learn all about it.