Skip to content

Instantly share code, notes, and snippets.

@bkeepers
Last active July 27, 2023 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bkeepers/cb3dd11e2eb9355672c46f1cdcebdec4 to your computer and use it in GitHub Desktop.
Save bkeepers/cb3dd11e2eb9355672c46f1cdcebdec4 to your computer and use it in GitHub Desktop.
Migrate from plain ol' delayed_job to ActiveJob without losing jobs in the queue when you deploy
# Allow legacy jobs in the queue to be initialized and processed now that they use ActiveJob
#
# Each job must also define `#init_with(coder)` to define how serialized instance variables are
# used to initialize the new ActiveJob instance.
module Delayed::LegacyJob
class Proxy < SimpleDelegator
# ActiveJob calls `#perform_now` internally when executing a job to pass arguments to `#perform`
def perform
perform_now
end
end
def payload_object
object = super
object.is_a?(ActiveJob::Base) ? Proxy.new(object) : object
end
end
# Allow deserializing legacy jobs that used to be a struct and are now a class
module Delayed::PsychExt::StructToObject
def visit_Psych_Nodes_Mapping(object)
if %r{^!ruby/struct:(.+)$} =~ object.tag
klass = resolve_class(Regexp.last_match[1]) rescue nil
return revive(klass, object) if klass
end
super(object)
end
end
module Delayed::ActiveJobInitWith
# Hook into DelayedJob/Psych's deserialization method to map `#perform` method
# parameters from instance variables of legacy jobs.
def init_with(coder)
initialize *method(:perform).parameters.map { |_, name| coder[name.to_s] }
end
end
Delayed::Job.include Delayed::LegacyJob
Delayed::PsychExt::ToRuby.include Delayed::PsychExt::StructToObject
ActiveJob::Base.include Delayed::ActiveJobInitWith
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment