4

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!

6
  • Add the request to the database (insert), have a separate process constantly checking the lowest id record which has not been processed, and process it Commented Nov 26, 2014 at 13:01
  • You would have to utilize something along the the lines of database or file locking. Each request in PHP is executed in its own process so it is going to be difficult to have objects "checking" each other unless you serialize and persist it in some fashion. Commented Nov 26, 2014 at 13:02
  • Why you need to do this? Commented Nov 26, 2014 at 13:08
  • Do you use class ? if you use you can do this : class Requests { private static $locked = false; static function process(){ if(self::$locked==true) { /*wait();*/ die('locked');//remove it } self::$locked=true; echo '..process...'; //self::$locked=false; } } \Requests::process(); \Requests::process(); Commented Nov 26, 2014 at 13:13
  • 1
    You probably need a Semaphore - en.wikipedia.org/wiki/Semaphore_(programming) php.net/manual/en/book.sem.php Commented Nov 26, 2014 at 13:13

2 Answers 2

3

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');
}
Sign up to request clarification or add additional context in comments.

1 Comment

Even though this is mentioned in a sub page of the Semaphore functions website, it should be noted that for this to work, the SysV Semaphores need to be enabled: php.net/manual/en/sem.installation.php#sem.installation
2

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);
}
?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.