Ich muss eine Aufgabe "CreateNotifications" in zufälligen Abständen der Zeit ausführen. Hier ist, was ich in den Einstellungen für CELLERY versucht habe.Nicht-periodische Wiederholung der Aufgabe in Django mit Sellerie
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),
},
}
Das Problem ist jetzt, dass diese Einstellungen für SELLERIE nur einmal ausgeführt werden (wenn ich den Befehl python manage.py runserver laufen), also die Variable ‚t‘ und damit der Wert von ‚Sekunden‘ in Timedelta bekommt ein zufälliger Wert, aber nur einmal.
Schließlich wird der obige Prozess zu einem periodischen mit einer festen Periode als X Sekunden, nur X wird zufällig ausgewählt, wenn ich Server starte.
Alternativ habe ich versucht, eine einzelne Aufgabe auszuführen und eine endlose While-Schleife darin mit einer zufälligen Verzögerung verwendet, so dass Sellerie nur eine Aufgabe automatisch erkennt und diese Aufgabe nie endet. Mein Zweck wird durch zufällige Verzögerung in der While-Schleife gelöst. Like this (HINWEIS -> ‚während‘ ist innerhalb der Funktion 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)
Seine Dinge genau so, wie ich will, aber jetzt gibt es 4 verschiedene Arbeiter die gleiche Aufgabe ausgeführt wird, aber ich möchte nur ein tun .
Ich habe versucht, Änderungen an celeryd Datei in meinem virtualenv/bin/Verzeichnis wie hier angegeben ->Celery. Decrease number of processes
, da es keine celeryd Datei in/etc/defaults ist/aber noch ohne Erfolg
Jede Hilfe wird geschätzt.
Dank @joshua. Mein Mentor an meinem Arbeitsplatz sagte mir dasselbe und es funktionierte. Danke trotzdem für die Antwort. Es ist der richtige Weg. Und ja, Endlosschleife sollte vermieden werden. Bei der Verwendung der Endlosschleife musste ich die Sellerie-Warteschlange jedes Mal löschen, um die Ausführung der Aufgaben mithilfe von SELLERY PURGE zu stoppen. Und diese 4 Arbeiter arbeiteten aufgrund der Tatsache, dass ich meine CreateNotifications.apply_async() 4 mal aus der Shell aufgerufen und sie nie aus der Warteschlange gelöscht hatte. –