0

I currently have the following:

try {
    $pheanstalk->useTube($tube)->put($data);
} catch (\Exception $e) {
    $logger = $this->container->get('logger');
    $logger->info('Could not reach beanstalk: ' . $e);
}

This works fine, but I want to have it where $pheanstalk->useTube($tube)->put($data) doesn't wait for a connection response from the server, and will just try to attempt to put the data on the queue and then continue on its merry way. The data this service is storing is nice to have, but isn't critical. Thus, during heavy load times I'd like to not have to wait for the timeout period before being able to continue with the rest of the program. How do I eliminate the wait for a response from the server part of pheanstalk?

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
Derick F
  • 2,749
  • 3
  • 20
  • 30

1 Answers1

0

To prevent blocking, you must fork your process.

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     // proceed with whatever
} else {
     // we are the child
     $exitStatus = -1;
     try {
         $pheanstalk->useTube($tube)->put($data);
         $exitStatus = 1;
     } catch (\Exception $e) {
         $logger = $this->container->get('logger');
         $logger->info('Could not reach beanstalk: ' . $e);
         $exitStatus = 0;
     }

     exit($exitStatus); 
}

What this does is fork your process and lets the child process wait around until pheanstalk returns. Note that there are some other concerns, though:

  • What if pheanstalk never returns? Your child process becomes a zombie.
  • Forking a process includes copying a lot of process variables. This is not without overhead, and therefore may not necessarily decrease your load. It might be worth it if whatever you're doing afterwards is the real work.

You could, in theory, pass a message to a local queuing system, on the same box, whose job it is to put messages on a remote system. This would get you a pretty fast response, but may require a lot more coding on your part. If you already have a local beanstalk instance, though, then this won't help. (I suspect you don't; local calls to beanstalk are fast. If you do have a local one the problem is probably on the worker/consumer end.)

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102