我需要以随机的时间间隔运行“CreateNotifications”任务。 以下是我在CELERY设置中尝试做的事情。
t = random.randint(45, 85)
## print "time = ", t
## celery app configuration
app.conf.CELERYBEAT_SCHEDULE = {
# Executes at every 't' interval, where t is random
'create-notifications': {
'task': 'apps.notifications.tasks.CreateNotifications',
'schedule': timedelta(seconds=t),
},
}
现在问题是CELERY的这些设置只执行一次(当我运行命令python manage.py runserver时),因此变量't'因此timedelta中'seconds'的值得到一个随机值,但只有一次。
最终使上述过程成为一个固定周期为X秒的周期过程,当我启动服务器时,只会随机选择X.
或者我尝试运行单个任务并在其中使用无限循环,并且随机延迟,以便芹菜只自动检测一个任务,该任务永远不会结束。我的目的是通过while循环中的随机延迟来解决的。 像这样(注意 - >'while'在函数CreateNotifications()中)
@app.task
def CreateNotifications():
while True:
upper_limit = models.MyUser.objects.all().aggregate(Max('id'))
lower_limit = models.MyUser.objects.all().aggregate(Min('id'))
## select a user to be notified randomly
to_user = None
to = 0
while to_user is None:
to = random.randint(lower_limit['id__min'], upper_limit['id__max'])
try:
to_user = models.MyUser.objects.get(id=to)
except:
pass
## select a user to be notified from randomly
frm_user = None
frm = to
while frm_user is None:
while frm == to:
frm = random.randint(lower_limit['id__min'], upper_limit['id__max'])
try:
frm_user = models.MyUser.objects.get(id=frm)
except:
pass
notif_type = ['comment on', 'liked', 'shared']
notif_media = ['post', 'picture', 'video']
models.Notification.objects.create(
notified_user = to_user,
notifier = frm_user,
notification_type = random.choice(notif_type),
notification_media = random.choice(notif_media))
to_user.new_notification_count += 1
to_user.save()
t = random.randint(35, 55)
print "delay = ", t
time.sleep(t)
它完全按照我的意愿行事,但现在有4个不同的工作人员执行相同的任务,但我只想要一个。
我已尝试更改位于我的virtualenv / bin /目录中的celeryd文件,如此处所示 - > Celery. Decrease number of processes
因为/ etc / defaults /中没有celeryd文件但仍然没有成功
任何帮助将不胜感激。
答案 0 :(得分:1)
你真的不应该在Celery任务中加入无限循环。如果你需要一个专门的过程,最好是自己运行它而不是通过Celery。
您可以在任务运行时重新安排新任务。如下所示:
@app.task
def create_notifications():
try:
#
finally:
t = random.randint(45, 85)
create_notifications.apply_async(countdown=t)
另一种选择是让调度程序任务按常规计划运行,但在不久的将来将通知任务排队一段随机时间。例如,如果调度程序任务每45秒运行一次。
@app.task
def schedule_notifications():
t = random.randint(0, 40)
create_notifications.apply_async(countdown=t)