3

I have a controller action for accepting the bulk user data, process data and then present the result. Since it is a tedious process, I am trying to assign the same to a worker and later present the results.

I need help with setting up the worker here.

My current procfile is

 web: vendor/bin/heroku-php-apache2
 worker: php yii hello/process

And I am testing it by running

public function actionTest(){
    $config  = require(__DIR__ . '/../config/console.php');
    $console = new \yii\console\Application($config);
    $console->runAction("hello/send");
}

Send Command

public function actionSend($message = 'hello world')
{
    $conn = $this->connection;
    $ch = $conn->channel();

    $exchange = 'amq.direct';
    $queue = 'basic_get_queue';
    $ch->queue_declare($queue, false, true, false, false);
    //$ch->exchange_declare($exchange, 'direct', true, true, false);
    //$ch->queue_bind($queue, $exchange);

    $msg_body = $message;
    $msg = new AMQPMessage($msg_body, array('content_type' => 'text/plain', 'delivery_mode' => 2));
    $ch->basic_publish($msg,'', $queue);

    /*      
    $retrived_msg = $ch->basic_get($queue);
    var_dump($retrived_msg->body);
    $ch->basic_ack($retrived_msg->delivery_info['delivery_tag']); */

    $ch->close();
    $conn->close();

}

Process Command

public function actionProcess(){
    $conn = $this->connection;
    $ch = $conn->channel(); 
    $queue = 'basic_get_queue';
    $ch->queue_declare($queue, false, true, false, false);

    //$retrived_msg = $ch->basic_get($queue);
    $callback = function($msg) {
        $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);         
        echo $msg->body;
    };
    $ch->basic_qos(null, 1, null);
    $ch->basic_consume($queue, '', false, false, false, false, $callback);
    // loop over incoming messages
    while(count($ch->callbacks)) {
        $ch->wait();
    }

    $ch->close();
    $conn->close();
}

But it is not triggering the worker!

I opened two terminals and tried and I could get the message echoed in the process command window.

Upon deploying, I could see the worker up and running

2017-03-13T10:25:24.114552+00:00 heroku[worker.1]: Starting process with command 'php yii hello/process'

2017-03-13T10:25:24.783227+00:00 heroku[worker.1]: State changed from starting to up

But worker is not triggering when I run the send command even from the terminal.

Please help!

Dency G B
  • 8,096
  • 9
  • 47
  • 78

1 Answers1

1

This is the final code which I got working! I will really appreciate if more better approaches are there to implement this.

Controller

public function actionTest($message){

    $url = parse_url(getenv('CLOUDAMQP_URL'));
    $conn = new AMQPConnection($url['host'], 5672, $url['user'], $url['pass'], substr($url['path'], 1));
    $ch = $conn->channel();

    $exchange = 'amq.direct';
    $queue = 'basic_get_queue';
    $ch->queue_declare($queue, false, true, false, false);

    $msg_body = $message;
    $msg = new AMQPMessage($msg_body, array('content_type' => 'text/plain', 'delivery_mode' => 2));
    $ch->basic_publish($msg,'', $queue);

    $ch->close();
    $conn->close();
}

Procfile

web: vendor/bin/heroku-php-apache2
worker: php yii hello/process

Command

public function actionProcess(){
    $url = parse_url(getenv('CLOUDAMQP_URL'));
    $conn = new AMQPConnection($url['host'], 5672, $url['user'], $url['pass'], substr($url['path'], 1));
    $ch = $conn->channel(); 
    $queue = 'basic_get_queue';
    $ch->queue_declare($queue, false, true, false, false);

    $callback = function($msg) {
        //save it for now
        $mesg = new Messages();
        $mesg->message = $msg->body;
        $mesg->save(false);
        $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);         

    };
    $ch->basic_qos(null, 1, null);
    $ch->basic_consume($queue, '', false, false, false, false, $callback);
    // loop over incoming messages
    while(count($ch->callbacks)) {
        $ch->wait();
    }
    $ch->close();
    $conn->close();
}

I use cloudamqp(https://elements.heroku.com/addons/cloudamqp) as my AMQP service. Do not forget to scale dynos for worker!

Dency G B
  • 8,096
  • 9
  • 47
  • 78