13
votes

I have below versions of celery and rabbitmq installed -

celery 3.1.6
rabbitmq 3.1.1

I can post a task to the default queue from PHP -

//client.php
<?php
require 'celery-php/celery.php';
$c = new Celery('localhost', 'guest', 'guest', '/');
$result = $c->PostTask('tasks.add', array(2,2));

My worker module is in python -

# tasks.py
from celery import Celery
celery = Celery('tasks', broker='amqp://guest:guest@localhost:5672//')
@celery.task(queue='demo', name='add')
def add(x, y):
    return x + y

I run the celery worker and client like this -

# terminal window 1
$ celery -A tasks worker --loglevel=info
# terminal window 2
$ php -f client.php

This works. I see below output in terminal window 1 :

Received task: tasks.add[php_52b1759141a8b3.43107845]
Task tasks.add[php_52b1759141a8b3.43107845] succeeded in 0.000701383920386s: 4

But I want to have different queues. For a demonstration, let's say I only want one queue called demo. So I run my celery worker like this -

$ celery -A tasks worker --loglevel=info -Q demo

But it's not working. The task is not getting executed. I guess it's probably because PHP code is posting the task on default queue : celery (apparently not on demo queue).

How do I post my task on a particular queue in PHP? Please help.

1
I guess I am gonna have go with different tasks instead of different queues if above thing is not possibile. - Hussain
You should check the source code of celery-php to see if there is a way to specify the exchange and routing_key of the task. In amqp you don't send messages to queues, you send them to exchanges which will then deliver the message to queues by matching the routing_key. There is a trick: you can set exchange="" and routing_key to the name of a queue (e.g. routing_key="demo" and it will deliver the message directly to the demo queue, bypassing the routing layer. - asksol
I am not that familiar with amqp. I'll go thorough the source code of celery-php and try above things. I'll let you know about it. Thanks for the reply. - Hussain

1 Answers

6
votes

By default, your PHP client for Celery takes the queue name as "celery".

In order to change the queue to publish to, you must specify the queue name while instantiating a connection to Celery. So, if you are starting your Celery worker with "-Q demo" option, then your connection to Celery in PHP should be -

$exchange = 'demo'; 
$binding = 'demo'; 
$c = new Celery('localhost', 'guest', 'guest', '/', $exchange, $binding); 

Note: With -Q option, the exchange and routing_key value is same as queue_name.

Please try this and share the results.

About exchange and binding :

With analogy to Telephone Services, Exchange is like "Telephone Operator", whose only job is to "Direct the call to YOU" with the help of routing_key.

Binding is then "Your Telephone Number", which acts as routing_key to your telephone.

Note : This process where exchange is redirecting the incoming message to the queue based on binding (routing_key), is a DIRECT exchange type. AMQP has few other types of exchanges, which you can read in AMQP documentation.

You can also refer this Celery page