1 What is Active Job?
Active Job es un marco para declarar trabajos y hacer que se ejecuten en una variedad de backends de cola. Estos trabajos pueden ser de cualquier cosa, desde ser programas que regularmente dan limpiezas, gastos de facturación, envíos postales. Todo lo que pueda cortarse en pequeñas unidades de trabajo y ejecutar en paralelo, de verdad.
2 The Purpose of Active Job
El punto principal es garantizar que todas las aplicaciones de Rails tengan una infraestructura de trabajo en su lugar. Luego podemos tener características de marco y otras gemas construidas sobre eso, sin tener que preocuparse por las diferencias de API entre varios corredores de trabajo, como trabajo retrasado y rescates. Elegir su backend de cola se vuelve más como una preocupación operacional. Y podrás cambiar entre ellos sin tener que volver a escribir sus trabajos.
Rails viene de forma predeterminada con una implementación de cola asincrónica que ejecuta trabajos con un grupo de subprocesos en proceso. Los trabajos se ejecutarán de forma asincrónica, pero cualquiera de los trabajos de la cola se eliminarán al reiniciar.
3 Creating a Job
Esta sección proporcionará una guía paso a paso para crear un trabajo y ponerlo en cola.
3.1 Create the Job
Active Job proporciona un generador de Rails para crear trabajos. Lo siguiente creará un
trabajo en app/jobs
(con un caso de prueba adjunto en test/jobs
):
$ bin/rails generate job guests_cleanup
invoke test_unit
create test/jobs/guests_cleanup_job_test.rb
create app/jobs/guests_cleanup_job.rb
También puede crear un trabajo que se ejecutará en una cola específica:
$ bin/rails generate job guests_cleanup --queue urgent
Si no desea utilizar un generador, puede crear su propio archivo dentro de
app/jobs
, solo asegúrate de que herede de ApplicationJob
.
Así es como se ve un trabajo:
class GuestsCleanupJob < ApplicationJob
queue_as :default
def perform(*guests)
# Do something later
end
end
Tenga en cuenta que puede definir perform
con tantos argumentos como desee.
3.2 Enqueue the Job
Ponga en cola un trabajo como este:
# Enqueue a job to be performed as soon as the queuing system is
# free.
GuestsCleanupJob.perform_later guest
# Enqueue a job to be performed tomorrow at noon.
GuestsCleanupJob.set(wait_until: Date.tomorrow.noon).perform_later(guest)
# Enqueue a job to be performed 1 week from now.
GuestsCleanupJob.set(wait: 1.week).perform_later(guest)
# `perform_now` and `perform_later` will call `perform` under the hood so
# you can pass as many arguments as defined in the latter.
GuestsCleanupJob.perform_later(guest1, guest2, filter: 'some_filter')
¡Eso es todo!
4 Job Execution
Para poner en cola y ejecutar trabajos en producción, debe configurar un backend de cola, es decir, debe decidir qué biblioteca de colas de terceros Rails debe de usar. Rails solo proporciona un sistema de cola en proceso, que solo mantiene los trabajos en RAM. Si el proceso falla o la máquina se reinicia, todos los trabajos pendientes se pierden con el backend asincrónico predeterminado. Esto puede estar bien para aplicaciones más pequeñas o trabajos que no son críticos, pero la mayoría de las aplicaciones de producción deberán elegir un backend persistente.
4.1 Backends
Active Job tiene adaptadores integrados para múltiples backends de cola (Sidekiq, Resque, Delayed Job y otros). Para obtener una lista actualizada de los adaptadores consulte la documentación de la API para ActiveJob::QueueAdapters.
4.2 Setting the Backend
Puede configurar fácilmente su backend de cola:
# config/application.rb
module YourApp
class Application < Rails::Application
# Be sure to have the adapter's gem in your Gemfile
# and follow the adapter's specific installation
# and deployment instructions.
config.active_job.queue_adapter = :sidekiq
end
end
También puede configurar su backend por trabajo.
class GuestsCleanupJob < ApplicationJob
self.queue_adapter = :resque
#....
end
# Now your job will use `resque` as its backend queue adapter overriding what
# was configured in `config.active_job.queue_adapter`.
4.3 Starting the Backend
Dado que los trabajos se ejecutan en paralelo a su aplicación Rails, la mayoría de las bibliotecas de colas requieren que inicie un servicio de cola específico de la biblioteca (además de iniciando su aplicación Rails) para que funcione el procesamiento del trabajo. Consulte la biblioteca documentación para obtener instrucciones sobre cómo iniciar el backend de la cola.
Here is a noncomprehensive list of documentation:
5 Queues
La mayoría de los adaptadores admiten varias colas. Con Active Job puede programar el trabajo para ejecutar en una cola específica:
class GuestsCleanupJob < ApplicationJob
queue_as :low_priority
#....
end
Puede prefijar el nombre de la cola para todos sus trabajos usando
config.active_job.queue_name_prefix
enapplication.rb
:
# config/application.rb
module YourApp
class Application < Rails::Application
config.active_job.queue_name_prefix = Rails.env
end
end
# app/jobs/guests_cleanup_job.rb
class GuestsCleanupJob < ApplicationJob
queue_as :low_priority
#....
end
# Now your job will run on queue production_low_priority on your
# production environment and on staging_low_priority
# on your staging environment
También puede configurar el prefijo por trabajo.
class GuestsCleanupJob < ApplicationJob
queue_as :low_priority
self.queue_name_prefix = nil
#....
end
# Now your job's queue won't be prefixed, overriding what
# was configured in `config.active_job.queue_name_prefix`.
El delimitador de prefijo de nombre de cola predeterminado es '\ '. Esto se puede cambiar configurando
`config.activejob.queue_name_delimiteren
application.rb`:
# config/application.rb
module YourApp
class Application < Rails::Application
config.active_job.queue_name_prefix = Rails.env
config.active_job.queue_name_delimiter = '.'
end
end
# app/jobs/guests_cleanup_job.rb
class GuestsCleanupJob < ApplicationJob
queue_as :low_priority
#....
end
# Now your job will run on queue production.low_priority on your
# production environment and on staging.low_priority
# on your staging environment
Si desea tener más control sobre qué cola se ejecutará un trabajo, puede pasar un : queue
opción a #set
:
MyJob.set(queue: :another_queue).perform_later(record)
Para controlar la cola desde el nivel de trabajo, puede pasar un bloque a #queue_as
.
El bloque se ejecutará en el contexto del trabajo (para que pueda acceder a self.arguments
)
y debe devolver el nombre de la cola:
class ProcessVideoJob < ApplicationJob
queue_as do
video = self.arguments.first
if video.owner.premium?
:premium_videojobs
else
:videojobs
end
end
def perform(video)
# Do process video
end
end
ProcessVideoJob.perform_later(Video.last)
Asegúrese de que su backend de cola "escuche" en su nombre de cola. Para algunos backends que necesita para especificar las colas para escuchar.
6 Callbacks
Active Job proporciona enlaces para activar la lógica durante el ciclo de vida de un trabajo. Me gusta otras devoluciones de llamada en Rails, puede implementar las devoluciones de llamada como métodos ordinarios y use un método de clase de estilo macro para registrarlos como devoluciones de llamada:
class GuestsCleanupJob < ApplicationJob
queue_as :default
around_perform :around_cleanup
def perform
# Do something later
end
private
def around_cleanup
# Do something before perform
yield
# Do something after perform
end
end
Los métodos de clase de estilo macro también pueden recibir un bloque. Considere usar esto style si el código dentro de su bloque es tan corto que cabe en una sola línea. Por ejemplo, puede enviar métricas para cada trabajo en cola:
class ApplicationJob < ActiveJob::Base
before_enqueue { |job| $statsd.increment "#{job.class.name.underscore}.enqueue" }
end
6.1 Available callbacks
before_enqueue
around_enqueue
after_enqueue
before_perform
around_perform
after_perform
7 Action Mailer
Uno de los trabajos más comunes en una aplicación web moderna es enviar correos electrónicos al exterior. del ciclo de solicitud-respuesta, por lo que el usuario no tiene que esperar. Trabajo activo está integrado con Action Mailer para que pueda enviar correos electrónicos fácilmente de forma asincrónica:
# If you want to send the email now use #deliver_now
UserMailer.welcome(@user).deliver_now
# If you want to send the email through Active Job use #deliver_later
UserMailer.welcome(@user).deliver_later
El uso de la cola asincrónica de una tarea Rake (por ejemplo, para
enviar un correo electrónico usando .deliver_later
) generalmente no funcionará porque Rake lo hará
probable final, lo que hace que se elimine el grupo de subprocesos en proceso, antes de cualquier/todos
de los correos electrónicos .deliver_later
se procesan. Para evitar este problema, utilice
.deliver_now
o ejecutar una cola persistente en desarrollo.
8 Internationalization
Cada trabajo usa el conjunto I18n.locale
cuando se creó el trabajo. Útil si envías
correos electrónicos de forma asincrónica:
I18n.locale = :eo
UserMailer.welcome(@user).deliver_later # Email will be localized to Esperanto.
9 Supported types for arguments
ActiveJob admite los siguientes tipos de argumentos de forma predeterminada:
- Tipos basicos (
NilClass
,String
,Integer
,Float
,BigDecimal
,TrueClass
,FalseClass
) Symbol
Date
Time
DateTime
ActiveSupport::TimeWithZone
ActiveSupport::Duration
-
Hash
(Las claves deben ser deString
o tipoSymbol
) ActiveSupport::HashWithIndifferentAccess
Array
Module
Class
9.1 GlobalID
Active Job admite GlobalID para parámetros. Esto hace posible pasar en vivo Active Record objetos a su trabajo en lugar de pares de clase/id, que luego tiene para deserializar manualmente. Antes, los trabajos se verían así:
class TrashableCleanupJob < ApplicationJob
def perform(trashable_class, trashable_id, depth)
trashable = trashable_class.constantize.find(trashable_id)
trashable.cleanup(depth)
end
end
Ahora puedes simplemente hacer:
class TrashableCleanupJob < ApplicationJob
def perform(trashable, depth)
trashable.cleanup(depth)
end
end
Esto funciona con cualquier clase que se mezcle en GlobalID::Identificación
, que
por defecto se ha mezclado con las clases Active Record.
9.2 Serializers
Puede ampliar la lista de tipos de argumentos admitidos. Solo necesita definir su propio serializador:
class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
# Checks if an argument should be serialized by this serializer.
def serialize?(argument)
argument.is_a? Money
end
# Converts an object to a simpler representative using supported object types.
# The recommended representative is a Hash with a specific key. Keys can be of basic types only.
# You should call `super` to add the custom serializer type to the hash.
def serialize(money)
super(
"amount" => money.amount,
"currency" => money.currency
)
end
# Converts serialized value into a proper object.
def deserialize(hash)
Money.new(hash["amount"], hash["currency"])
end
end
y agregue este serializador a la lista:
Rails.application.config.active_job.custom_serializers << MoneySerializer
10 Exceptions
Active Job proporciona una forma de detectar excepciones generadas durante la ejecución del trabajo:
class GuestsCleanupJob < ApplicationJob
queue_as :default
rescue_from(ActiveRecord::RecordNotFound) do |exception|
# Do something with the exception
end
def perform
# Do something later
end
end
Si la excepción no se rescata dentro del trabajo, p. Ej. como se muestra arriba, el trabajo se denomina "fallido".
10.1 Retrying or Discarding failed jobs
Un trabajo fallido no se reintentará, a menos que se configure de otra manera.
También es posible reintentar o descartar un trabajo si se genera una excepción durante la ejecución. Por ejemplo:
class RemoteServiceJob < ApplicationJob
retry_on CustomAppException # defaults to 3s wait, 5 attempts
discard_on ActiveJob::DeserializationError
def perform(*args)
# Might raise CustomAppException or ActiveJob::DeserializationError
end
end
Para obtener más detalles, consulte la documentación de la API para ActiveJob::Exceptions.
10.2 Deserialization
GlobalID permite serializar objetos Active Record completos pasados a # perform
.
Si un registro aprobado se elimina después de que el trabajo se pone en cola pero antes del # perform
El método se llama Active Job generará un ActiveJob::DeserializationError
excepción.
11 Job Testing
Puede encontrar instrucciones detalladas sobre cómo probar sus trabajos en el testing guide.
Comentarios Sobre el Contenido
Las guías de rieles se administran y publican en latinadeveloper/railsguides.es en GitHub.
Si lee esta guía y encuentra algún texto o código incorrecto que le interese, no dude en enviar una solicitud de extracción en el repositorio anterior. Consulte el archivo README en GitHub para saber cómo enviar una solicitud de extracción. Please contribute if you see any typos or factual errors.