Ich habe eine Tonne Forschung zu diesem Thema, und ich bin überrascht, ich habe noch nirgendwo eine gute Antwort gefunden.Capture Heroku SIGTERM in Sellerie Arbeiter zum Herunterfahren Arbeiter anmutig
Ich habe eine große Anwendung auf Heroku ausgeführt, und ich habe bestimmte Sellerie Aufgaben, die für eine sehr lange Zeit Verarbeitung ausgeführt werden, und am Ende der Aufgabe speichern Sie ein Ergebnis. Jedes Mal, wenn ich es auf Heroku umsetze, sendet es SIGTERM (und eventuell SIGKILL) und tötet meinen laufenden Arbeiter. Ich versuche, eine Möglichkeit für die Worker-Instanz zu finden, sich selbst ordnungsgemäß herunterzufahren und sich zur späteren Verarbeitung neu einzuordnen, damit wir schließlich das erforderliche Ergebnis speichern können, anstatt die Aufgabe in der Warteschlange zu verlieren.
Ich kann einen Weg nicht finden, der funktioniert, damit der Arbeiter auf SIGTERM richtig hört. Der nächstgelegene ich bekommen habe, das funktioniert, wenn python manage.py celeryd
direkt aber NICHT laufen, wenn die Emulation Heroku Vorarbeiter verwenden, ist die folgende:
@app.task(bind=True, max_retries=1)
def slow(self, x):
try:
for x in range(100):
print 'x: ' + unicode(x)
time.sleep(10)
except exceptions.MaxRetriesExceededError:
logger.error('whoa')
except (exceptions.WorkerShutdown, exceptions.WorkerTerminate) as exc:
logger.error(u'retrying, ' + unicode(exc))
raise self.retry(exc=exc, countdown=10)
except (KeyboardInterrupt, SystemExit) as exc:
print 'retrying'
raise self.retry(exc=exc, countdown=10)
else:
return x
finally:
logger.info('task ended!')
Wenn ich diesen Sellerie Aufgabe beginnen innerhalb Vorarbeiter laufen und drücken Sie Strg + C, die passiert folgendes:
^CSIGINT received
22:20:59 system | sending SIGTERM to all processes
22:20:59 web.1 | exited with code 0
22:21:04 system | sending SIGKILL to all processes
Killed: 9
es ist so klar, dass keine der Sellerie Ausnahmen, noch die KeyboardInterrupt
oder SystemExit
Ausnahmen ich in anderen Beiträgen gesehen habe, richtig SIGTERM fangen und den Arbeiter herunterzufahren.
Was ist der richtige Weg?
http://celery.readthedocs.org/en/latest/userguide/workers.html?highlight=sigkill#process-signals scheint darauf hinzuweisen, dass der Hauptarbeiter immer SIGTERM abfängt. –
Richtig - gibt es irgendeinen Weg, den Hauptarbeiter zu den Kindern zu bringen? – jdotjdot
Dies ist ein Problem, das ich auch nie eine großartige Lösung gefunden habe. Ich tendiere dazu, es in der Anwendungslogik zu handhaben, indem ich sicherstelle, dass meine Aufgaben idempotent sind, und dass die Verfolgung gestartet und Aufgaben abgeschlossen werden, sodass ich eine bestimmte Aufgabe beim Start meiner Anwendung automatisch neu starten kann. –