Wenn Sie dies unter https://github.com/collectiveidea/delayed_job anzeigen, lesen Sie die Dokumentation für den Master -Zweig. Dokumentation für die neueste Version (4.1.13) anzeigen.
Verspätet :: Job (oder DJ) verkaps das gemeinsame Muster der asynchronen Ausführung längerer Aufgaben im Hintergrund.
Es handelt sich um eine direkte Extraktion von Shopify, bei der die Jobtabelle für eine Vielzahl von Kernaufgaben verantwortlich ist. Unter diesen Aufgaben sind:
Massive Newsletter senden
Bildänderung
HTTP -Downloads
Aktualisieren intelligenter Sammlungen
Aktualisieren von Solr, unserem Suchserver, nach den Produktänderungen
Batchimporte
Spam prüft
Folgen Sie uns auf Twitter, um Updates und Mitteilungen über neue Veröffentlichungen zu erhalten.
Delayed_job 3.0.0 unterstützt nur Rails 3.0+.
Delyed_Job unterstützt mehrere Backends für die Speicherung der Jobwarteschlange. Siehe das Wiki für andere Backends.
Wenn Sie vorhaben, Delyed_job mit einem aktiven Datensatz zu verwenden, fügen Sie Ihrer Gemfile
delayed_job_active_record
hinzu.
Gem 'Delyed_job_active_record' '
Wenn Sie planen, Delyed_job mit Mongoid zu verwenden, fügen Sie Ihrer Gemfile
delayed_job_mongoid
hinzu.
Gem 'Delayed_job_Mongoid'
Führen Sie bundle install
um die Backend- und Delyed_Job -Edelsteine zu installieren.
Das aktive Backend -Backend erfordert eine Jobtabelle. Sie können diese Tabelle erstellen, indem Sie den folgenden Befehl ausführen:
rails generate delayed_job:active_record rake db:migrate
Für Rails 4.2+ siehe unten
Wenn Sie im Entwicklungsmodus Rails 3.1+ verwenden, laden Ihr Anwendungscode automatisch alle 100 Jobs oder nach Abschluss der Warteschlange neu. Sie müssen nicht mehr jedes Mal, wenn Sie Ihren Code in der Entwicklung aktualisieren, verzögerte Arbeiten mehr neu starten.
Legen Sie in Rails 4.2+ das Queue_Adapter in config/application.rb ein
config.active_job.queue_adapter =: Delayed_job
Weitere Informationen finden Sie im Rails Guide.
Wenn Sie das Edelstein protected_attributes verwenden, muss es vor dem Delyed_Job in Ihrer GemFile erscheinen. Wenn Ihre Jobs mit:
ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR: null value in column "handler" violates not-null constraint
Dann ist dies die Fix, die Sie suchen.
Der verzögerte Job 3.0.0 führt eine neue Spalte in die Tabelle Delayed_jobs ein.
Wenn Sie von Delayed Job 2.x aktualisieren, führen Sie den Upgrade -Generator aus, um eine Migration zu erstellen, um die Spalte hinzuzufügen.
rails generate delayed_job:upgrade rake db:migrate
Rufen Sie .delay.method(params)
auf jedem Objekt auf, und es wird im Hintergrund verarbeitet.
# ohne verzö[email protected]! (@device)# mit verzö[email protected]! (@device)
Wenn eine Methode immer im Hintergrund ausgeführt werden sollte, können Sie #handle_asynchronously
nach der Methodeerklärung aufrufen:
Klassengerät Def liefern# Langlauf -Methode Ende Handle_asynchron: lieferenddevice = devement.newDevice.deliver
#handle_asynchronously
und #delay
nehmen diese Parameter:
:priority
(Nummer): Niedrigere Zahlen werden zuerst ausgeführt; Standard ist 0, kann aber neu konfiguriert werden (siehe unten)
:run_at
(Zeit): Führen Sie den Job nach dieser Zeit aus (wahrscheinlich in der Zukunft)
:queue
(String): Named Queue, um diesen Job einzulegen, eine Alternative zu Prioritäten (siehe unten)
Diese Parameter können Proc-Objekte sein, die die Anrufzeitbewertung des Wertes ermöglichen.
Zum Beispiel:
Klasse Longtasks Def send_mailer# ein anderer Code Ende Handle_asynchron: send_mailer ,: priority => 20 Def in_the_Future# ein anderer Code Ende # 5.minutes.from_now wird bewertet, wenn in_the_future aufgerufen wird handle_asynchron: in_the_future ,: run_at => proc.new {5.Minutes.from_now} def self self.when_to_run2.hourss.from_now Ende Klasse << selfdef CALL_A_CLASS_METHOD # Ein anderer Codeendhandle_asynchronous: CALL_A_CLASS_METHOD ,: Ende Attr_reader: How_important Def call_an_instance_method# ein anderer Code Ende handle_asynchron: call_an_instance_method ,: priority => proc.new {| i | I.Wow_important} Ende
Wenn Sie jemals eine handle_asynchronously
'D -Methode ohne verzögerten Job aufrufen möchten, z. B. beim Debuggen von etwas an der Konsole, fügen Sie einfach _without_delay
dem Method -Namen hinzu. Wenn Ihre ursprüngliche Methode beispielsweise foo
war, rufen Sie foo_without_delay
auf.
Verspäteter Job verwendet spezielle Syntax für Rails Mailer. Rufen Sie die .deliver
-Methode nicht an, wenn Sie .delay
verwenden.
# ohne Delyed_Jobnotifier.signup (@User) .Deliver# mit delayed_jobnotifier.delay.signup (@User)# Delyed_job, die in einem bestimmten Timenotifier.delay (run_at: 5.Minutes.from_now) ausgeführt wird .Signup (@User)############### , Die Methode. Die Methode muss vor dem .delay methodNotifier.with (foo: 1, balken: 2) .Delay.signup (@User) aufgerufen werden.
Möglicherweise möchten Sie auch in Betracht ziehen, Active Jobs mit Action Mailer zu verwenden, das eine bequeme .deliver_later
Syntax bietet, die sich an verzögerte Arbeit unter dem Haus weiterleitet.
DJ 3 führt mit dem benannten Warteschlangen im Resque-Stil ein und behält gleichzeitig die Priorität im DJ-Stil bei. Ziel ist es, ein System für die Gruppierung von Aufgaben zur Verfügung zu stellen, die von getrennten Arbeitnehmern bearbeitet werden können, die einzeln skaliert und kontrolliert werden können.
Jobs können einer Warteschlange zugewiesen werden, indem die queue
festgelegt wird:
Object.Delay (: Queue => 'Tracking'). MethodDelayed :: Job.Enqueue Job ,: Queue => 'Tracking'Handle_asynchron: tweet_later,: queue =>' Tweets '
Sie können Standardprioritäten für benannte Warteschlangen konfigurieren:
Verspätet :: Worker.queue_attributes = {{ High_Priority: {Priorität: -10}, Low_Priority: {Priorität: 10}}
Konfigurierte Warteschlangenprioritäten können überschrieben werden, indem Priorität an die Verzögerungsmethode weitergegeben wird
Object.Delay (: Queue => 'High_Priority', Priorität: 0) .Method
Sie können Prozesse starten, um nur bestimmte Warteschlangen mit den unten definierten queue
und queues
zu bearbeiten. Prozesse, ohne die Warteschlange anzugeben, werden Jobs aus jeder Warteschlange ausführen. Um effektiv einen Prozess zu haben, in dem Jobs ausgeführt werden, in denen eine Warteschlange nicht angegeben ist, setzen Sie einen Standard -Warteschlangenname mit Delayed::Worker.default_queue_name
und lassen Sie die Prozesse diese Warteschlange ausführen.
script/delayed_job
kann verwendet werden, um einen Hintergrundprozess zu verwalten, der auf Jobs arbeitet.
Fügen Sie zu Ihrem Gemfile
gem "daemons"
hinzu und stellen Sie sicher, dass Sie rails generate delayed_job
.
Sie können dann Folgendes tun:
RAILS_ENV=production script/delayed_job start RAILS_ENV=production script/delayed_job stop # Runs two workers in separate processes. RAILS_ENV=production script/delayed_job -n 2 start RAILS_ENV=production script/delayed_job stop # Set the --queue or --queues option to work from a particular queue. RAILS_ENV=production script/delayed_job --queue=tracking start RAILS_ENV=production script/delayed_job --queues=mailers,tasks start # Use the --pool option to specify a worker pool. You can use this option multiple times to start different numbers of workers for different queues. # The following command will start 1 worker for the tracking queue, # 2 workers for the mailers and tasks queues, and 2 workers for any jobs: RAILS_ENV=production script/delayed_job --pool=tracking --pool=mailers,tasks:2 --pool=*:2 start # Runs all available jobs and then exits RAILS_ENV=production script/delayed_job start --exit-on-complete # or to run in the foreground RAILS_ENV=production script/delayed_job run --exit-on-complete
Schienen 4: Skript/Delyed_job durch Bin/Delyed_job ersetzen
Arbeiter können auf jedem Computer ausgeführt werden, solange sie Zugriff auf die Datenbank haben und ihre Uhr synchronisiert ist. Denken Sie daran, dass jeder Arbeiter die Datenbank mindestens alle 5 Sekunden überprüft.
Sie können auch rake jobs:work
aufrufen, die anfangen, Jobs zu bearbeiten. Sie können die Rake-Aufgabe mit CTRL-C
stornieren.
Wenn Sie einfach alle verfügbaren Jobs ausführen und beenden möchten, können Sie rake jobs:workoff
verwenden
Arbeiten Sie die Warteschlangen aus, indem Sie die Umgebungsvariable der QUEUE
oder QUEUES
einstellen.
QUEUE=tracking rake jobs:work QUEUES=mailers,tasks rake jobs:work
Die folgende Syntax startet verzögerte Jobs neu:
RAILS_ENV=production script/delayed_job restart
So starten Sie mehrere Delyed_Job -Arbeiter neu:
RAILS_ENV=production script/delayed_job -n2 restart
Schienen 4: Skript/Delyed_job durch Bin/Delyed_job ersetzen
Jobs sind einfache Ruby -Objekte mit einer Methode namens Perform. Jedes Objekt, auf das reagiert, kann in den Jobtisch gestopft werden. Jobobjekte werden mit YAML serialisiert, damit sie später vom Jobläufer wiederbelebt werden können.
Newsletterjob = struct.new (: Text,: E -Mails) tun Def PerformeMails.each {| e | NewSletterTerMailer.deliver_text_to_email (Text, e)} EndendDelayed :: Job.Enqueue Newsletterjob.New ('Lorem Ipsum ...', Kunden.pluck (: E -Mail))
So setzen
Newsletterjob = struct.new (: Text,: E -Mails) tun Def PerformeMails.each {| e | NewSletterTerMailer.deliver_text_to_email (Text, e)} Ende Def Max_attempts3 Endend
So setzen
HINWEIS: Dies kann nur verwendet werden, um eine max_run_time festzulegen, die niedriger ist als verzögerte :: Worker.max_run_time. Andernfalls würde die Schloss für den Job auslaufen und ein anderer Arbeiter würde die Arbeit mit dem laufenden Job beginnen.
Newsletterjob = struct.new (: Text,: E -Mails) tun Def PerformeMails.each {| e | NewSletterTerMailer.deliver_text_to_email (Text, e)} Ende Def Max_run_time120 # Sekunden Endend
Um einen Standard für die Zerstörung fehlgeschlagener Jobs zu setzen, die die Verzögerung :: Worker.destroy_Failed_Jobs überschreiben, können Sie eine Destroy_Failed_Jobs definieren? Methode bei der Arbeit
Newsletterjob = struct.new (: Text,: E -Mails) tun Def PerformeMails.each {| e | NewSletterTerMailer.deliver_text_to_email (Text, e)} Ende Def DESTREIDE_FAILED_JOBS? FALSE Endend
Um einen Standard -Warteschlangennamen für einen benutzerdefinierten Job festzulegen, der Delayed :: Worker.default_queue_Name überschreibt, können Sie eine Queue_Name -Methode für den Job definieren
Newsletterjob = struct.new (: Text,: E -Mails) tun Def PerformeMails.each {| e | NewSletterTerMailer.deliver_text_to_email (Text, e)} Ende Def queue_name'newsletter_queue ' Endend
Bei Fehler ist der Job in 5 Sekunden erneut geplant + n ** 4, wobei n die Anzahl der Versuche ist. Sie können Ihre eigene reschedule_at
methode definieren, um dieses Standardverhalten zu überschreiben.
Newsletterjob = struct.new (: Text,: E -Mails) tun Def PerformeMails.each {| e | NewSletterTerMailer.deliver_text_to_email (Text, e)} Ende Def -redule_at (current_time, Versuche) current_time + 5.Sekunden Endend
Sie können Hooks an Ihrem Job definieren, die in verschiedenen Phasen im Prozess aufgerufen werden:
Hinweis: Wenn Sie ActiveJob verwenden, stehen diesen Haken Ihren Jobs nicht zur Verfügung. Sie müssen ActiveJobs Rückrufe verwenden. Hier finden Sie Details hier https://guides.rubyonrails.org/active_job_basics.html#callbacks
Klassen paranoidnewsletterjob <Newsletterjob Def Enqueue (Job) record_stat 'Newsletter_job/enqueue' ' Ende Def PerformeMails.each {| e | NewSletterTerMailer.deliver_text_to_email (Text, e)} Ende Def vor (Job) record_stat 'Newsletter_job/start' Ende Def After (Job) record_stat 'Newsletter_job/After' Ende Def Success (Job) record_stat 'Newsletter_job/Erfolg' Ende Def Fehler (Job, Ausnahme) Airbrake.notify (Ausnahme) Ende Def Failure (Job) page_sysadmin_in_the_middle_of_the_night Endend
Die Bibliothek dreht sich um eine Tabelle Delayed_Jobs, die wie folgt aussieht:
create_table: Delayed_jobs,: force => true do | Tabelle | table.integer: priority,: default => 0 # Ermöglicht einige Jobs, an die Vorderseite der Warteschlange zu springen Table.Integer: Versuche,: default => 0 # bietet Wiederholungen, aber es scheitern immer noch. Tabelle.Text: Handler # yaml-kodierter Zeichenfolge des Objekts, das funktioniert table.text: last_error # Grund für den letzten Fehler (siehe Hinweis unten) table.datetime: run_at # Wenn zu laufen. Könnte Zeit sein. table.datetime: locked_at # setzen, wenn ein Client an diesem Objekt arbeitet table.datetime: failed_at # setzen, wenn alle Wiederholungen fehlgeschlagen sind (tatsächlich wird der Datensatz tatsächlich gelöscht) Tabelle.String: Locked_by # Wer arbeitet an diesem Objekt (falls gesperrt) Tabelle.String: Warteschlange # Der Name der Warteschlange in diesem Job ist in table.timestampsend
Bei Fehler ist der Job in 5 Sekunden erneut geplant + n ** 4, wobei n die Anzahl der Versuche oder die definierte reschedule_at
-Methode des Jobs verwendet.
Der Standard Worker.max_attempts
ist 25. Danach wird der Job entweder gelöscht (Standard) oder in der Datenbank mit "failed_at" -Set gelassen. Mit dem Standard von 25 Versuchen wird der letzte Wiederholung 20 Tage später sein, wobei der letzte Intervall fast 100 Stunden beträgt.
Der Standard Worker.max_run_time
ist 4. Stunden. Wenn Ihr Job länger dauert, kann ein anderer Computer ihn abholen. Es liegt an Ihnen, sicherzustellen, dass Ihr Job diesmal nicht übertrifft. Sie sollten dies auf die längste Zeit setzen, in der Sie denken, dass der Job annehmen könnte.
Standardmäßig löscht es gescheiterte Jobs (und es löscht immer erfolgreiche Jobs). Wenn Sie fehlgeschlagene Jobs beibehalten möchten, setzen Sie Delayed::Worker.destroy_failed_jobs = false
. Die fehlgeschlagenen Jobs werden mit Nicht-Null-Failed_at markiert.
Standardmäßig sind alle Jobs mit priority = 0
geplant, was oberste Priorität hat. Sie können dies ändern, indem Delayed::Worker.default_priority
auf etwas anderes festlegen. Niedrigere Zahlen haben eine höhere Priorität.
Das Standardverhalten besteht darin, 5 Jobs aus der Warteschlange zu lesen, wenn Sie einen verfügbaren Job finden. Sie können dies konfigurieren, indem Delayed::Worker.read_ahead
einstellen.
Standardmäßig werden alle Jobs ohne benannte Warteschlange in die Warteschlange gestellt. Eine Standard -Warteschlange kann angegeben werden, indem Delayed::Worker.default_queue_name
verwendet wird.
Wenn keine Arbeitsplätze gefunden werden, schläft der Arbeitnehmer für die Zeitspanne, die durch die Option für die Schlafverzögerung angegeben ist. Setzen Sie Delayed::Worker.sleep_delay = 60
für eine 60 -Sekunden -Schlafzeit.
Es ist möglich, verzögerte Arbeitsplätze für Testzwecke zu deaktivieren. Setzen Sie Delayed::Worker.delay_jobs = false
um alle Jobs in Echtzeit auszuführen.
Oder Delayed::Worker.delay_jobs
kann ein Proc sein, der entscheidet, ob Jobs in der Basis pro Arbeit inline ausgeführt werden sollen:
Delayed :: Worker.delay_jobs = -> (Job) { Job.queue! = 'inline'}
Möglicherweise müssen Sie Ausnahmen von Sigterm -Signalen aufnehmen, Delayed::Worker.raise_signal_exceptions = :term
veranlasst den Arbeitnehmer, eine SignalException
zu erhöhen, die den laufenden Job abbricht und entsperrt wird, was den Auftrag anderen Arbeitnehmern zur Verfügung stellt. Die Standardeinstellung für diese Option ist falsch.
Hier ist ein Beispiel für die Änderung der Jobparameter in Schienen:
# config/Initializer/Delyed_job_config.rbdelayed :: Worker.destroy_failed_jobs = falsedelayed :: Worker.sleep_delay = 60Delayed :: Worker AME = 'default'delayed :: Worker.delay_jobs =! tails.env.test? Delayed :: Worker.raise_signal_exceptions =: termdelayed :: Worker.logger = logger.new (File.join (Rails.Reot),' log ',', ',', ',', ',', ',', ',', ',', ',', ',', ',' Delyed_job.log '))))
Sie können rake jobs:clear
um alle Jobs in der Warteschlange zu löschen.
Gute Orte, um Hilfe zu bekommen, sind:
Google Gruppen, wo Sie unserer Mailingliste beitreten können.
Stackoverflow