delayed_job. Eliminar trabajo de la cola

class Radar
 include Mongoid::Document
 after_save :post_on_facebook

 private

 def post_on_facebook
  if self.user.settings.post_facebook
    Delayed::Job.enqueue(::FacebookJob.new(self.user,self.body,url,self.title),0,self.active_from)
  end
 end

end

class FacebookJob < Struct.new(:user,:body,:url,:title)
  include SocialPluginsHelper

  def perform
    facebook_client(user).publish_feed('', :message => body, :link => url, :name => title)
  end
end

Quiero ejecutar el método post_on_facebook en una fecha específica. Guardo esta fecha en el campo "active_from".

El código anterior funciona y el trabajo se ejecuta en la fecha correcta.

Pero en algunos casos, primero creo un objeto Radar y envío algún trabajo a la cola de Trabajo retrasado. Después de eso, actualizo este objeto y envío otro trabajo a Trabajo retrasado.

Este es un comportamiento incorrecto porque no quiero ejecutar el trabajo solo una vez en el momento correcto. En esta implementación tendré 2 trabajos que se ejecutarán. ¿Cómo puedo eliminar el trabajo anterior para que solo se ejecute uno actualizado?

Rails 3.0.7
Delayed Job => 2.1.4 https://github.com/collectiveidea/delayed_job

ps: perdón por mi inglés, trato de hacer lo mejor que puedo

preguntado el 16 de mayo de 11 a las 19:05

2 Respuestas

Parece que desea retirar cualquier trabajo de la cola si un objeto de radar se actualiza y se vuelve a poner en cola.

Delayed :: Job.enqueue debería devolver un registro de Delayed :: Job, para que pueda tomar la ID de ahí y guardarlo en el registro de Radar (cree un campo para él en el documento de radar) para que pueda encontrarlo de nuevo más tarde fácilmente .

Debe cambiarlo a before_save para que no ingrese un ciclo infinito de guardado.

before_save :post_on_facebook

def post_on_facebook
  if self.user.settings.post_facebook && self.valid?

    # delete existing delayed_job if present
    Delayed::Job.find(self.delayed_job_id).destroy if self.delayed_job_id

    # enqueue job
    dj = Delayed::Job.enqueue(
      ::FacebookJob.new(self.user,self.body,url,self.title),0,self.active_from
    )

    # save id of delayed job on radar record
    self.delayed_job_id = dj.id

  end
end

contestado el 17 de mayo de 11 a las 01:05

@Unixmonkey ... ¿y si el trabajo se está creando en el after_save llamar de vuelta. - Rohit

@Rohit the after_save ejecutará este método, y el delayed_job_id no se establecerá en el registro (porque no puede llamar a save en after_save sin que ingrese en un bucle infinito) - Unixmonkey

¿Intentó almacenar la identificación del trabajo retrasado y luego almacenarla para una posible eliminación?

job_id = Delayed::Job.enqueue(::FacebookJob.new(self.user,self.body,url,self.title),0,self.active_from)
job = Delayed::Job.find(job_id)
job.delete

contestado el 17 de mayo de 11 a las 01:05

Curiosamente, si Delayed :: Worker.delay_jobs = false, esto se romperá ya que parece que la operación de puesta en cola simplemente ejecuta el trabajo, nunca lo guarda en la base de datos - Kevin Davis

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.