这是我第一次使用Celery,老实说,我不确定我做得对。我的系统必须在Windows上运行,所以我使用RabbitMQ作为代理。
作为一个概念证明,我正在尝试创建一个对象,其中一个任务设置值,另一个任务读取值,我还想显示当我转到某个URL时对象的当前值。但是我在一切之间分享对象时遇到了问题。
这是我的celery.py
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE','cesGroundStation.settings')
app = Celery('cesGroundStation')
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
@app.task(bind = True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
我想分享的对象是:
class SchedulerQ():
item = 0
def setItem(self, item):
self.item = item
def getItem(self):
return self.item
这是我的tasks.py
from celery import shared_task
from time import sleep
from scheduler.schedulerQueue import SchedulerQ
schedulerQ = SchedulerQ()
@shared_task()
def SchedulerThread():
print ("Starting Scheduler")
counter = 0
while(1):
counter += 1
if(counter > 100):
counter = 0
schedulerQ.setItem(counter)
print("In Scheduler thread - " + str(counter))
sleep(2)
print("Exiting Scheduler")
@shared_task()
def RotatorsThread():
print ("Starting Rotators")
while(1):
item = schedulerQ.getItem()
print("In Rotators thread - " + str(item))
sleep(2)
print("Exiting Rotators")
@shared_task()
def setSchedulerQ(schedulerQueue):
schedulerQ = schedulerQueue
@shared_task()
def getSchedulerQ():
return schedulerQ
我正在apps.py中开始我的任务...我不确定这是不是正确的地方,因为任务/工作人员似乎没有工作,直到我在一个单独的控制台中启动工作人员运行celery -A cesGroundStation -l info
。
from django.apps import AppConfig
from scheduler.schedulerQueue import SchedulerQ
from scheduler.tasks import SchedulerThread, RotatorsThread, setSchedulerQ, getSchedulerQ
class SchedulerConfig(AppConfig):
name = 'scheduler'
def ready(self):
schedulerQ = SchedulerQ()
setSchedulerQ.delay(schedulerQ)
SchedulerThread.delay()
RotatorsThread.delay()
在我的views.py中,我有这个:
def schedulerQ():
queue = getSchedulerQ.delay()
return HttpResponse("Your list: " + queue)
django应用程序运行没有错误,但是“celery -A cesGroundStation -l info”的输出是这样的:Celery command output
首先它似乎启动了多个“SchedulerThread”任务,其次“SchedulerQ”对象没有被传递给Rotators,因为它没有读取更新的值。
如果我转到显示views.schedulerQ视图的url,我会收到此错误: Django views error
我对Python,Django和Web开发的总体经验非常非常少,所以我不知道从哪里开始最后一个错误。解决方案建议使用Redis将对象传递给视图,但我不知道如何使用RabbitMQ做到这一点。稍后,schedulerQ对象将实现一个队列,并且调度程序和旋转器将充当生产者/消费者动态,并且视图显示队列的内容,因此我认为使用数据库可能过于耗费资源。如何在所有任务中共享此对象,这是否是正确的方法?
答案 0 :(得分:0)
正确的方法是使用一些持久层,例如数据库或results back end来存储您想要在任务之间共享的信息,如果您需要在任务之间共享信息(在此示例中,您是什么目前正在上课。)
Celery在分布式消息传递范例上运行 - 这个例子提炼出这个想法的好方法是,每次调度任务时,您的模块都将独立执行。每当将任务分派给Celery时,您必须假设它在单独的解释器中运行并且独立于其他任务加载。每次都会重新实例化SchedulerQ
类。
您可以按照之前链接的文档中描述的方式在某些任务之间共享信息,并且可以讨论一些best practice tips讨论数据持久性问题。