Module: Joblin::Uniqueness::Compat::Sidekiq

Defined in:
lib/joblin/uniqueness/compat/sidekiq.rb

Defined Under Namespace

Modules: WorkerExtension Classes: ClientMiddleware, CommonMiddleware, ServerMiddleware, SidekiqLockContext

Constant Summary collapse

ACTIVE_JOB_WRAPPERS =

Sidekiq 8 renamed the ActiveJob wrapper class. Accept both so ActiveJob-based jobs keep their unique-job handling across Sidekiq 7 and 8.

[
  'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper',
  'Sidekiq::ActiveJob::Wrapper',
].freeze

Class Method Summary collapse

Class Method Details

.configureObject



129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/joblin/uniqueness/compat/sidekiq.rb', line 129

def self.configure
  sidekiq_middleware(:client) do |chain|
    chain.insert_before Joblin::Batching::Compat::Sidekiq::ClientMiddleware, Compat::Sidekiq::ClientMiddleware
  end

  sidekiq_middleware(:server) do |chain|
    chain.insert_after Joblin::Batching::Compat::Sidekiq::ServerMiddleware, Compat::Sidekiq::ServerMiddleware
  end

  ::Sidekiq::Worker.extend(ActiveSupport::Concern) unless ::Sidekiq::Worker < ActiveSupport::Concern

  ::Sidekiq::Worker.send(:include, Compat::Sidekiq::WorkerExtension)
end

.is_activejob_job?(msg) ⇒ Boolean

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
91
# File 'lib/joblin/uniqueness/compat/sidekiq.rb', line 83

def self.is_activejob_job?(msg)
  return false unless defined?(::ActiveJob)
  return false unless ACTIVE_JOB_WRAPPERS.include?(msg['class'])

  # `wrapped` comes from the job payload; use safe_constantize so a
  # malformed/unknown value yields nil rather than raising NameError.
  wrapped = msg['wrapped'].to_s.safe_constantize
  !!(wrapped && wrapped < Compat::ActiveJob::UniqueJobExtension)
end

.sidekiq_middleware(placement, &blk) ⇒ Object



100
101
102
103
104
105
106
107
108
109
# File 'lib/joblin/uniqueness/compat/sidekiq.rb', line 100

def self.sidekiq_middleware(placement, &blk)
  install_middleware = ->(config) do
    config.send("#{placement}_middleware") do |chain|
      blk.call(chain)
    end
  end

  ::Sidekiq.configure_client(&install_middleware) if placement == :client
  ::Sidekiq.configure_server(&install_middleware)
end

.validate_middleware_order(chain, order) ⇒ Object



93
94
95
96
97
98
# File 'lib/joblin/uniqueness/compat/sidekiq.rb', line 93

def self.validate_middleware_order(chain, order)
  chain_classes = chain.entries.map(&:klass)
  filtered = chain_classes.select { |klass| order.include?(klass) }
  raise "Middleware chain does not contain all required middleware: #{order - filtered}" unless order.all? { |klass| filtered.include?(klass) }
  raise "Middleware must be in order: #{order.inspect}" if filtered != order
end

.validate_middleware_placement!Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/joblin/uniqueness/compat/sidekiq.rb', line 111

def self.validate_middleware_placement!
  sidekiq_middleware(:client) do |chain|
    # Unique middleware must come _before_ the Batch middleware so that the uniqueness middleware can wrap the job in a batch
    validate_middleware_order(chain, [
      Joblin::Uniqueness::Compat::Sidekiq::ClientMiddleware,
      Joblin::Batching::Compat::Sidekiq::ClientMiddleware,
    ])
  end

  sidekiq_middleware(:server) do |chain|
    # Unique middleware must com _after_ the Batch middleware so that the Batch is loaded before reaching the uniqueness middleware
    validate_middleware_order(chain, [
      Joblin::Batching::Compat::Sidekiq::ServerMiddleware,
      Joblin::Uniqueness::Compat::Sidekiq::ServerMiddleware,
    ])
  end
end