53 lines
1.8 KiB
Ruby
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
|