Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create php blocking mechanism on concurrent requests?

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!

like image 799
corvax Avatar asked Sep 14 '25 10:09

corvax


2 Answers

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');
}
like image 174
madebydavid Avatar answered Sep 17 '25 03:09

madebydavid


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);
}
?>
like image 36
Karel Kubat Avatar answered Sep 17 '25 01:09

Karel Kubat