otwarchive-symphonyarchive/app/models/concerns/async_with_resque.rb
2026-03-11 22:22:11 +00:00

53 lines
1.8 KiB
Ruby

# frozen_string_literal: true
# A module used to make it easy to call asynchronous methods on ActiveRecord
# objects (both on the class and on the instance).
module AsyncWithResque
extend ActiveSupport::Concern
include AfterCommitEverywhere
# The instance version of the async function. Uses perform_on_instance so
# that we can use the same perform() function for instance methods and class
# methods.
def async(method, *args)
self.class.async(:perform_on_instance, id, method, *args)
end
class_methods do
# The class version of the async function. Uses base_class so that we
# handle subclasses properly.
def async(method, *args)
Resque.enqueue(base_class, method, *args)
end
# Actually perform the delayed action.
def perform(method, *args)
if method.is_a?(Integer)
# TODO: For backwards compatibility, if the "method" is an integer, we
# treat it like an ID and use perform_on_instance instead. But once all
# of the jobs in the queue have been processed (or deleted), we should
# be able to remove this check.
perform_on_instance(method, *args)
else
send(method, *args)
end
end
# Find the instance with the given ID, and call the method on it instead.
# This function allows us to use the same perform() function for both class
# functions and instance functions.
def perform_on_instance(id, method, *args)
find(id).send(method, *args)
end
end
# A function that can be used to help with stale data issues. Instead of
# immediately adding the desired action to the Resque queue the way that
# async() does, it uses AfterCommitEverywhere to call async() after the
# commit has gone through.
def async_after_commit(*args)
after_commit do
async(*args)
end
end
end