How to create php blocking mechanism on concurrent requests?

2.7k Views Asked by At

Say I have an application recieving concurrent requests. User A and B send requests same time, I need to process requests in a queue.

I need something like this:

function processRequests() {
  if(locked()) {
    wait();
  }

  $this->lock();
  ...process...
  $this->unlock();
}

Is there any packages or patterns helping to solve this problem?

PLEASE DON'T OFFER ANY "MESSAGE QUEUE SERVER" SOLUTIONS!

2

There are 2 best solutions below

1
On BEST ANSWER

Using PHP's Semaphore functions, you can implement a simple locking system which will try to acquire a lock based on a key which identifies the resource you want to lock. The sem_acquire function will block and wait until the semaphore can be acquired:

$sm = sem_get(getmyinode() + hexdec(substr(md5("identifier to lock"), 24)));

if (sem_acquire($sm)) {

    ...process...

    sem_release($sm);
    sem_remove($sm);

} else {
    throw new \Exception('unable to acquire semaphore');
}
0
On

You could abuse flock() to make your own semaphore. The line flock($f, LOCK_EX) will block until another process releases the lock in flock($f, LOCK_UN). More at php.net.

<?php
if (! ($f = fopen('/dev/null', 'r')) )
    print('Oops, no /dev/null on this system?\n');
else {
    flock($f, LOCK_EX);
    print("I have the lock, I can do stuff now.\n");
    sleep(3);
    print("I am done, releasing.\n");
    flock($f, LOCK_UN);
    fclose($f);
}
?>