我正在将我从Golang编写的应用程序(使用redis)移植到Python上,我很乐意使用Celery完成我的任务排队,但我对路由有疑问...
我的应用程序通过REST POST接收“事件”,其中每个“事件”可以是不同类型。然后,我希望让工作人员在后台等待某些类型的事件。这里需要注意的是,ONE事件可能导致处理事件的任务超过一个。例如:
一些/ LIB /一个/ tasks.py
@task
def handle_event_typeA(a,b,c):
# handles event...
pass
@task
def handle_event_typeB(a,b,c):
# handles other event...
pass
一些/ LIB / B / tasks.py
@task
def handle_event_typeA(a,b,c):
# handles event slightly differently... but still same event...
pass
总之......我希望能够运行N个工作者(跨X个机器),并且这些工作中的每一个都将注册Y个任务,例如:a.handle_event_typeA,b.handle_event_typeA,等...我希望能够将一个任务插入队列,并让一个工作人员接收任务并将其路由到工作人员中的多个任务(即同时指向a.handle_event_typeA和b.handle_event_typeA)。 / p>
我已经阅读了Kombu here和Celery的路由文档here的文档,我似乎无法弄清楚如何正确配置它。
我一直在使用Celery一段时间来处理更传统的工作流程,我对它的功能集,性能和稳定性非常满意。我会直接使用Kombu或一些自制解决方案实现我需要的东西,但我想尽可能使用Celery。
谢谢你们!我希望我不会浪费任何人的时间来处理这个问题。
经过一段时间思考这个问题后,我想出了一个解决方法来实现我想要的Celery。这不是最优雅的解决方案,但它运作良好。我正在使用django并且它是缓存抽象(你可以直接使用像memcached或redis这样的东西)。这是我想出的片段:
from django.core.cache import cache
from celery.execute import send_task
SUBSCRIBERS_KEY = 'task_subscribers.{0}'
def subscribe_task(key, task):
# get current list of subscribers
cache_key = SUBSCRIBERS_KEY.format(key)
subscribers = cache.get(cache_key) or []
# get task name
if hasattr(task, 'delay'):
name = task.name
else:
name = task
# add to list
if not name in subscribers:
subscribers.append(name)
# set cache
cache.set(cache_key, subscribers)
def publish_task(key, *kargs):
# get current list of subscribers
cache_key = SUBSCRIBERS_KEY.format(key)
subscribers = cache.get(cache_key) or []
# iterate through all subscribers and execute task
for task in subscribers:
# send celery task
send_task(task, args=kargs, kwargs={})
我接下来要做的是通过执行以下操作来订阅不同模块中的任务:
subscribe_task('typeA', 'some.lib.b.tasks.handle_event_typeA')
然后我可以在处理REST事件时调用发布任务方法。