Module: Easyop::Plugins::Async

Defined in:
lib/easyop/plugins/async.rb

Overview

Enables async execution via ActiveJob.

Usage:

class Newsletter::SendBroadcast < ApplicationOperation
  plugin Easyop::Plugins::Async, queue: "broadcasts"
end

# Enqueue immediately:
Newsletter::SendBroadcast.call_async(subject: "Hello", body: "World")

# With scheduling options:
Newsletter::SendBroadcast.call_async(attrs, wait: 10.minutes)
Newsletter::SendBroadcast.call_async(attrs, wait_until: Date.tomorrow.noon)
Newsletter::SendBroadcast.call_async(attrs, queue: "low_priority")

ActiveRecord objects are serialized by (class, id) and re-fetched in the job. Only serializable values (String, Integer, Float, Boolean, nil, Hash, Array, or ActiveRecord::Base) should be passed.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Class Method Details

.install(base, queue: "default", **_options) ⇒ Object



24
25
26
27
# File 'lib/easyop/plugins/async.rb', line 24

def self.install(base, queue: "default", **_options)
  base.extend(ClassMethods)
  base.instance_variable_set(:@_async_default_queue, queue)
end

.job_classObject

The ActiveJob that deserializes and runs the operation. Defined lazily so this file can be required before ActiveJob loads.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/easyop/plugins/async.rb', line 83

def self.job_class
  @job_class ||= begin
    raise LoadError, "ActiveJob is required for Easyop::Plugins::Async" unless defined?(ActiveJob::Base)

    klass = Class.new(ActiveJob::Base) do
      queue_as :default

      def perform(operation_class, attrs)
        op_klass = operation_class.constantize
        deserialized = attrs.each_with_object({}) do |(k, v), h|
          h[k.to_sym] = if v.is_a?(Hash) && v["__ar_class"]
                           v["__ar_class"].constantize.find(v["__ar_id"])
                         else
                           v
                         end
        end
        op_klass.call(deserialized)
      end
    end

    # Give the anonymous class a constant name for serialization
    Easyop::Plugins::Async.const_set(:Job, klass) unless const_defined?(:Job)
    klass
  end
end