How to do cakephp parallel processing and return api response with callback?


I'm trying to make an api with cakephp 3. With this api I'll send some information for batch email to the system. After storing the api request into databse I want to return an acknowledgement that the request has received and start batch processing. After finishing the processing I want to send a callback response to return the process status. In my current coding system I've to wait to finish the process. How can I do it parallely?

    // Store api request to database
    $saveQueue = EmailQueue::enqueue($to, $data, $options);

    if ($saveQueue) {
        $this->Flash->success('Request saved in queue.');

        $shell = new ShellDispatcher();
        $output = $shell->run(['cake', 'EmailQueue.sender']);

        if (0 === $output) {
            $this->Flash->success('Success from shell command.');
        } else {
            $this->Flash->error('Failure from shell command.');

    $this->Flash->error('Failed to save in queue.'); 

[I'm not sure what should be the actual question title, feel free to edit. :) ]

Show source
| cakephp   | asynchronous   | php   | cakephp-3.0   | parallel-processing   2017-01-07 13:01 1 Answers

Answers ( 1 )

  1. 2017-01-08 19:01

    You system is broken by design. Don't use a shell in a web environment. They're for a reason two different worlds. Honestly, I'm to lazy to write an exhaustive explanation what else is wrong with that approach but here is a proper soltuion:

    1. API receives data via POST
    2. Application creates task and puts it in queue
    3. API responds with something like "OK job put in queue, here is your job ID"
    4. A shell, that runs on the server in the background (NOT in the request), is processing the queue

    Now there are two options:

    • Once the task is done the application sends a POST request back to the system that created the task, to a defined endpoint and informs it that the task is done
    • The system that created the tasks does every X minutes a GET request against your API asking if it's queued job is done or not and receives the status in return. This should be cached to limit requests and the response communicate the lifetime of the cache.

    First is the better solution.

    Another solution would be Websockets if you want to have long running realtime information about the status of the queue.

◀ Go back