Se você estiver visualizando isso em https://github.com/collectiveidea/delayed_job, você estará lendo a documentação da filial mestre. Ver documentação para a versão mais recente (4.1.13).
O atraso :: Job (ou DJ) encapsula o padrão comum de executar tarefas mais longas assíncronas em segundo plano.
É uma extração direta do Shopify, onde a tabela de trabalho é responsável por uma infinidade de tarefas principais. Entre essas tarefas estão:
Enviando boletins enormes
redimensionamento da imagem
Downloads HTTP
Atualizando coleções inteligentes
Atualizando Solr, nosso servidor de pesquisa, após alterações do produto
importações de lote
Verificações de spam
Siga -nos no Twitter para obter atualizações e avisos sobre novos lançamentos.
touched_job 3.0.0 suporta apenas Rails 3.0+.
touched_job suporta vários backnds para armazenar a fila de empregos. Veja o wiki para outros back -ends.
Se você planeja usar o ADELADO_JOB com registro ativo, adicione delayed_job_active_record
ao seu Gemfile
.
Gem 'touched_job_active_record'
Se você planeja usar o atraso_job com mongóides, adicione delayed_job_mongoid
ao seu Gemfile
.
Gem 'touched_job_mongoid'
Execute bundle install
para instalar as gemas back -end e touched_job.
O back -end de registro ativo requer uma tabela de empregos. Você pode criar essa tabela executando o seguinte comando:
rails generate delayed_job:active_record rake db:migrate
Para o Rails 4.2+, veja abaixo
No modo de desenvolvimento, se você estiver usando o Rails 3.1+, o código do seu aplicativo recarregará automaticamente a cada 100 trabalhos ou quando a fila terminar. Você não precisa mais reiniciar o trabalho atrasado toda vez que atualiza seu código em desenvolvimento.
No Rails 4.2+, defina o queue_adapter em config/application.rb
config.active_job.queue_adapter =: touched_job
Veja o guia Rails para obter mais detalhes.
Se você estiver usando o GEM Protected_attributes, ele deve aparecer antes do atraso_JOB no seu GemFile. Se seus empregos estiverem falhando:
ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR: null value in column "handler" violates not-null constraint
Então esta é a correção que você está procurando.
Jó retardado 3.0.0 Apresenta uma nova coluna na tabela touched_jobs.
Se você estiver atualizando do trabalho atrasado 2.x, execute o gerador de atualização para criar uma migração para adicionar a coluna.
rails generate delayed_job:upgrade rake db:migrate
Ligue para .delay.method(params)
em qualquer objeto e ele será processado em segundo plano.
# sem [email protected]! (@dispositivo)# com [email protected]! (@dispositivo)
Se um método sempre deve ser executado em segundo plano, você poderá ligar para #handle_asynchronously
após a declaração do método:
dispositivo de classe def entregar# método de longa execução fim handle_asynchronsly: DeliveNDDevice = device.newdevice.deliver
#handle_asynchronously
e #delay
pegam esses parâmetros:
:priority
(número): números mais baixos são executados primeiro; O padrão é 0, mas pode ser reconfigurado (veja abaixo)
:run_at
(tempo): execute o trabalho após esse período (provavelmente no futuro)
:queue
(string): nomeada na fila para colocar esse trabalho, uma alternativa às prioridades (veja abaixo)
Esses parâmetros podem ser objetos PROC, permitindo a avaliação do tempo de chamada do valor.
Por exemplo:
Classe LongTasks def send_mailer# algum outro código fim handle_asynchronsly: send_mailer ,: prioridade => 20 def in_the_future# algum outro código fim # 5.Minutes.From_now será avaliado quando in_the_future for chamado handle_asynchronsly: in_the_future ,: run_at => proc.new {5.minutes.from_now} def self.when_to_run2.hours.from_now fim Classe << Selfdef Call_A_Class_Method # Algum outro código CodeEndHandle_asynchronsly: Call_a_class_method ,: run_at => proc.new {when_to_run} fim att_reader: How_important Def Call_AN_Instance_Method# algum outro código fim handle_asynchronsly: call_an_instance_method ,: priority => proc.new {| i | i.ow_important} end
Se você deseja chamar um método handle_asynchronously
'D sem emprego atrasado, por exemplo, ao depurar algo no console, basta adicionar _without_delay
ao nome do método. Por exemplo, se o seu método original foi foo
, ligue para foo_without_delay
.
O trabalho retardado usa sintaxe especial para correios de trilhos. Não chame o método .deliver
ao usar .delay
.
# sem touched_jobnotifier.signup (@User) .Deliver# com touched_jobnotifier.delay.signup (@user)# touched_job em um timeNotifier específico.delay (run_at: 5.minutes.from_now) .Signup (@USER)# , o método .with deve ser chamado antes do .Delay MethodNotifier.with (Foo: 1, bar: 2) .Delay.signup (@User)
Você também pode considerar o uso de trabalho ativo com o ACOD Mailer, que fornece uma sintaxe conveniente .deliver_later
que encaminha para o atraso no trabalho sob o alojamento.
O DJ 3 apresenta as filas de estilo resque chamadas, mantendo a prioridade do estilo de DJ. O objetivo é fornecer um sistema para agrupar tarefas a serem trabalhadas por grupos separados de trabalhadores, que podem ser dimensionados e controlados individualmente.
Os trabalhos podem ser atribuídos a uma fila definindo a opção queue
:
object.Delay (: fila => 'rastreamento'). MethodDelayed :: job.enqueue Job ,:
Você pode configurar prioridades padrão para filas nomeadas:
Atrasado :: trabalhador.queue_attributes = { high_priority: {prioridade: -10}, Low_priority: {prioridade: 10}}
As prioridades da fila configuradas podem ser superestimadas, passando a prioridade do método de atraso
object.Delay (: fila => 'High_Priority', prioridade: 0) .Method
Você pode iniciar processos para trabalhar apenas certas filas com as opções queue
e queues
definidas abaixo. Os processos iniciados sem especificar uma fila executarão trabalhos de qualquer fila. Para ter efetivamente um processo que executa trabalhos em que uma fila não é especificada, defina um nome de fila padrão com Delayed::Worker.default_queue_name
e faça com que os processos executem essa fila.
script/delayed_job
pode ser usado para gerenciar um processo de fundo que começará a trabalhar fora dos trabalhos.
Para fazer isso, adicione gem "daemons"
ao seu Gemfile
e verifique se você executa rails generate delayed_job
.
Você pode fazer o seguinte:
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
Rails 4: Substitua o script/touched_job por bin/touched_job
Os trabalhadores podem estar em execução em qualquer computador, desde que tenham acesso ao banco de dados e seu relógio esteja sincronizado. Lembre -se de que cada trabalhador verificará o banco de dados pelo menos a cada 5 segundos.
Você também pode invocar rake jobs:work
que começará a trabalhar em trabalhos. Você pode cancelar a tarefa de rake com CTRL-C
.
Se você quiser apenas executar todos os trabalhos e saídas disponíveis, pode usar rake jobs:workoff
Trabalhe filas definindo a variável de ambiente QUEUE
ou QUEUES
.
QUEUE=tracking rake jobs:work QUEUES=mailers,tasks rake jobs:work
A sintaxe a seguir reiniciará os empregos atrasados:
RAILS_ENV=production script/delayed_job restart
Para reiniciar vários trabalhadores tardios_job:
RAILS_ENV=production script/delayed_job -n2 restart
Rails 4: Substitua o script/touched_job por bin/touched_job
Trabalhos são objetos simples de rubi com um método chamado Perform. Qualquer objeto que responda ao desempenho pode ser recheado na tabela de empregos. Os objetos de emprego são serializados para a YAML para que possam ser ressuscitados mais tarde pelo corredor de trabalho.
Newsletterjob = struct.new (: texto, e e -mails) def performails.each {| e | NewsLeTterMailer.deliver_text_to_email (texto, e)} ENDENDDELAYED :: JOB.ENQUEUE NEWSLETTERJOB.NEW ('LOREM IPSUM ...', Customers.pluck (: Email))
Para definir uma tentativa de MAX por trabalho que substitui o atraso :: worker.max_attempts, você pode definir um método max_attemps no trabalho
Newsletterjob = struct.new (: texto, e e -mails) def performails.each {| e | NewsLeTterMailer.deliver_text_to_email (texto, e)} fim def max_attempts3 Endura
Para definir um tempo de execução PER-Job Max que substitui o atraso :: trabalhador.max_run_time, você pode definir um método max_run_time no trabalho
NOTA: Isso só pode ser usado para definir um max_run_time que seja menor que o atraso :: trabalhador.max_run_time. Caso contrário, o bloqueio do trabalho expiraria e outro trabalhador começaria a trabalhar no trabalho em andamento.
Newsletterjob = struct.new (: texto, e e -mails) def performails.each {| e | NewsLeTterMailer.deliver_text_to_email (texto, e)} fim def max_run_time120 # segundos Endura
Para definir um padrão por JOB para destruir trabalhos fracassados que substituem o atraso :: trabalhador.destroy_failed_jobs, você pode definir um Destroy_failed_jobs? Método no trabalho
Newsletterjob = struct.new (: texto, e e -mails) def performails.each {| e | NewsLeTterMailer.deliver_text_to_email (texto, e)} fim def destruir_failed_jobs? false Endura
Para definir um nome de fila padrão para um trabalho personalizado que substitui o atraso :: worker.default_queue_name, você pode definir um método da fila_name no trabalho
Newsletterjob = struct.new (: texto, e e -mails) def performails.each {| e | NewsLeTterMailer.deliver_text_to_email (texto, e)} fim def Queue_name'newsletter_queue ' Endura
Por erro, o trabalho está agendado novamente em 5 segundos + n ** 4, onde n é o número de tentativas. Você pode definir seu próprio método reschedule_at
para substituir esse comportamento padrão.
Newsletterjob = struct.new (: texto, e e -mails) def performails.each {| e | NewsLeTterMailer.deliver_text_to_email (texto, e)} fim Def Reschedule_at (current_time, tentativas) current_time + 5.segundos Endura
Você pode definir ganchos em seu trabalho que serão chamados em diferentes estágios do processo:
Nota: Se você estiver usando o ActiveJob, esses ganchos não estão disponíveis para seus trabalhos. Você precisará usar os retornos de chamada do ActiveJob. Você pode encontrar detalhes aqui https://guides.rubyonrails.org/active_job_basics.html#callbacks
Classe ParanoidNewsletterJob <NewsletterJob Def Enqueue (Job) Record_stat 'Newsletter_job/Enqueue' fim def performails.each {| e | NewsLeTterMailer.deliver_text_to_email (texto, e)} fim def fim def após (Job) record_stat 'Newsletter_job/depois' fim Def Succed (Job) Record_stat 'Newsletter_job/Success' fim ERRO DE DEF (Job, exceção) AirBrake.Notify (exceção) fim def Fail (Job) Page_sysadmin_in_the_middle_of_the_night Endura
A biblioteca gira em torno de uma tabela tardia_jobs que parece a seguir:
create_table: touched_jobs ,: force => true do | tabela | tabela.Integer: prioridade ,: padrão => 0 # permite tabela.Integer: Tentativas ,: padrão => 0 # fornece tentativas, mas ainda falham eventualmente. tabela.text: manipulador # string codificada por Yaml do objeto que funcionará tabela.Text: last_error # Motivo da última falha (veja a nota abaixo) tabela.dateTime: run_at # Quando executar. Pode ser hora.Zone. agora imediatamente, ou em algum momento no futuro. tabela.DateTime: Locked_at # Definir quando um cliente está trabalhando neste objeto tabela.dateTime: falhou_at # Definir quando todas as tentativas falharam (na verdade, por padrão, o registro é excluído) Table.String: Locked_by # Quem está trabalhando neste objeto (se bloqueado) tabela.String: fila # o nome da fila Este trabalho está em tabela.TimestampSend
Sobre o erro, o trabalho está agendado novamente em 5 segundos + n ** 4, onde n é o número de tentativas ou usando o método reschedule_at
definido do trabalho.
O Worker.max_attempts
padrão.Max_Attempts é 25. Depois disso, o trabalho é excluído (padrão) ou deixado no banco de dados com o conjunto "falhas_at". Com o padrão de 25 tentativas, a última tentativa será 20 dias depois, com o último intervalo sendo quase 100 horas.
O Worker.max_run_time
padrão.max_run_time é 4.hours. Se o seu trabalho levar mais tempo, outro computador poderá buscá -lo. Cabe a você garantir que seu trabalho não exceda desta vez. Você deve definir isso para mais tempo que você acha que o trabalho poderia assumir.
Por padrão, ele excluirá trabalhos com falha (e sempre exclui trabalhos bem -sucedidos). Se você deseja manter os trabalhos com falha, defina Delayed::Worker.destroy_failed_jobs = false
. Os trabalhos fracassados serão marcados com falhas não-null.
Por padrão, todos os trabalhos estão agendados com priority = 0
, que é a principal prioridade. Você pode alterar isso definindo Delayed::Worker.default_priority
para outra coisa. Números mais baixos têm maior prioridade.
O comportamento padrão é ler 5 empregos da fila ao encontrar um trabalho disponível. Você pode configurar isso definindo Delayed::Worker.read_ahead
.
Por padrão, todos os trabalhos serão filmados sem uma fila nomeada. Uma fila nomeada padrão pode ser especificada usando Delayed::Worker.default_queue_name
.
Se não forem encontrados trabalhos, o trabalhador dorme pelo tempo especificado pela opção de atraso do sono. Definir Delayed::Worker.sleep_delay = 60
por um tempo de sono de 60 segundos.
É possível desativar trabalhos atrasados para fins de teste. Definir Delayed::Worker.delay_jobs = false
para executar todos os trabalhos em tempo real.
Ou Delayed::Worker.delay_jobs
pode ser um proc que decida se deve executar empregos em linha por uma base por trabalho:
Atrasado :: trabalhador.delay_jobs = -> (Job) { Job.queue! = 'Inline'}
Pode ser necessário aumentar as exceções sobre os sinais do SigTerm, Delayed::Worker.raise_signal_exceptions = :term
fará com que o trabalhador elevará uma SignalException
fazendo com que o trabalho em execução seja abortado e desbloqueado, o que disponibiliza o trabalho para outros trabalhadores. O padrão para esta opção é falso.
Aqui está um exemplo de mudança de parâmetros de trabalho em trilhos:
# Config/Initializers/Atraso_job_config.rbdelayed :: worker.destroy_failed_jobs = FalsedElayed :: Worker.sleep_delay = 60Delayed :: Worker.max_attsempts = 3Delayed :: Worker.max_run_time = 5.minues nome = 'Default'DaLayed :: Worker.Delay_Jobs =! Rails.env.test? Atraso :: trabalhador.raise_signal_exceptions =: TermDelayed :: Worker.logger = Logger.new (file.join (Rails.root,' log ',' touched_job.log '))
Você pode invocar rake jobs:clear
para excluir todos os empregos na fila.
Bons lugares para obter ajuda são:
Grupos do Google, onde você pode ingressar na nossa lista de e -mails.
Stackoverflow