Search code examples
phpasynchronousphalconamazon-elastic-beanstalkbeanstalkd

Calling a function from beanstalk


I have a function in PHP that does some task that needs to call another function asynchronously.

function doTask1() {
    // some task
    asyncTask()
}

I did some research and was told I need to use beanstalk to achieve the same, but I am confused about how to achieve it, As I am not able to find any documentation or tutorials to do the same.

heres what the async function looks like

function asyncTask(){
// raise an event
console.log("event raised");
}

The idea is the function doTask1() should go ahead and complete irrespective of whatever happens in asyncTask();.


Solution

  • The way we manage this here is to launch the second task from a php cli.

    In Task1 :

    1. Put the params you want to pass to the async function in a tube
    2. call a script with your async function
    3. Continue your Task1...

    In Task2 :

    1. Open Beanstalk tube
    2. retrieve the params
    3. do what you need !
    function doTask1() {
        // some task
    
        // 1. Open the tube (here in a Phalcon framework app) and fill the params
        $queue = $this->di->getShared("queue", ["tube" => "myAsyncTube"]);
        $idQueue = $queue->put([
            "myparam1" => $this->param1,
            "myparam2" => $this->param2
        ],[
            "priority" => 250,
            "delay" => 10, 
            "ttr" => 3600 
        ]);
    
        // 2. Call the async task (man bash !)
        exec('bash -c "exec nohup setsid php -q /var/www/asyncTask.php /dev/null 2>&1 &"');
    
        // finish some tasks
    }
    

    And in the asyncTask.php :

    <?php
        // 1. Get the tube
        $queue = $this->di->getShared("queue", ["tube" => "myAsyncTube"]);
        // 2. Execute all the queued tasks of the tube
        While($job = $queue->peekReady() !== false){
              $job = $queue->reserve();
              $message = $job->getBody();
    
              $this->param1 = $message['param1'];
              $this->param2 = $message['param2'];
    
              // Do all the time consuming job you want !
        }
    

    Notes on the bash params :

    • nohup : detach job from session (so it will continue)
    • setsid : in a new session (separate env)
    • php : could be almost any executable binary you want !
    • /var/www/asyncTask.php : the file with your second function
    • /dev/null 2>&1 : we don't need logs so redirect all to trash
    • & : this one is the key : run this backward and return to the prompt, so the exec() could finish, and the task1 could continue !

    Notice also that as the task2 runs in backward, it can't return something to task1, but it can put the response in an other tube to notify other subscribers that the task is done, etc. !

    ++

    Rom1deTroyes