Skip to content

Commit e015991

Browse files
dixpacsimi
authored andcommitted
Add ActiveJob adapter
Implements adapter for `ActiveJob` inside the gem. This adapter is defined only if rails version is >=8, for earlier rails versions adapter is definied inside the Rails itself
1 parent 40db4fb commit e015991

File tree

5 files changed

+122
-0
lines changed

5 files changed

+122
-0
lines changed

kicks.gemspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Gem::Specification.new do |gem|
3131
gem.add_dependency 'rake', '>= 12.3', '< 14.0'
3232

3333
# for integration environment (see .travis.yml and integration_spec)
34+
gem.add_development_dependency 'activejob', '>= 7.1'
35+
gem.add_development_dependency 'activesupport', '>= 7.1'
3436
gem.add_development_dependency 'rabbitmq_http_api_client'
3537
gem.add_development_dependency 'redis'
3638

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module ActiveJob
2+
module QueueAdapters
3+
# Explicitly remove the implementation existing in older rails'.
4+
remove_const(:SneakersAdapter) if defined?(:SneakersAdapter)
5+
6+
# = Sneakers adapter for Active Job
7+
#
8+
# To use Sneakers set the queue_adapter config to +:sneakers+.
9+
#
10+
# Rails.application.config.active_job.queue_adapter = :sneakers
11+
class SneakersAdapter < ::ActiveJob::QueueAdapters::AbstractAdapter
12+
def initialize
13+
@monitor = Monitor.new
14+
end
15+
16+
def enqueue(job)
17+
@monitor.synchronize do
18+
JobWrapper.from_queue job.queue_name
19+
JobWrapper.enqueue ActiveSupport::JSON.encode(job.serialize)
20+
end
21+
end
22+
23+
def enqueue_at(job, timestamp)
24+
raise NotImplementedError, 'This queueing backend does not support scheduling jobs.'
25+
end
26+
27+
class JobWrapper
28+
include Sneakers::Worker
29+
from_queue 'default'
30+
31+
def work(msg)
32+
job_data = ActiveSupport::JSON.decode(msg)
33+
Base.execute job_data
34+
ack!
35+
end
36+
end
37+
end
38+
end
39+
end

lib/sneakers.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module Concerns
2222
require 'sneakers/middleware/config'
2323
require 'sneakers/worker'
2424
require 'sneakers/publisher'
25+
require 'active_job/queue_adapters/sneakers_adapter' if defined?(ActiveJob)
26+
2527

2628
module Sneakers
2729
extend self

spec/fixtures/test_job.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
require 'sneakers'
2+
require 'redis'
3+
4+
redis_addr = compose_or_localhost('redis')
5+
puts "REDIS is at #{redis_addr}"
6+
$redis = Redis.new(host: redis_addr)
7+
8+
9+
class TestJob < ActiveJob::Base
10+
def perform(message)
11+
$redis.incr('rails_active_job')
12+
end
13+
end
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
require 'spec_helper'
2+
require 'sneakers'
3+
require 'sneakers/runner'
4+
require 'rabbitmq/http/client'
5+
require 'active_job'
6+
require 'active_job/queue_adapters/sneakers_adapter'
7+
require 'fixtures/test_job'
8+
9+
describe 'ActiveJob integration' do
10+
before :each do
11+
skip unless ENV['INTEGRATION']
12+
prepare
13+
end
14+
15+
def integration_log(msg)
16+
puts msg if ENV['INTEGRATION_LOG']
17+
end
18+
19+
def rmq_addr
20+
@rmq_addr ||= compose_or_localhost('rabbitmq')
21+
end
22+
23+
def prepare
24+
ActiveJob::Base.queue_adapter = :sneakers
25+
26+
Sneakers.clear!
27+
Sneakers.configure(amqp: "amqp://guest:guest@#{rmq_addr}:5672")
28+
Sneakers.logger.level = Logger::ERROR
29+
30+
redis_addr = compose_or_localhost('redis')
31+
@redis = Redis.new(host: redis_addr)
32+
@redis.del('rails_active_job')
33+
end
34+
35+
def wait_for_jobs_to_finish
36+
sleep 5
37+
end
38+
39+
def start_active_job_workers
40+
integration_log 'starting ActiveJob workers.'
41+
runner = Sneakers::Runner.new([ActiveJob::QueueAdapters::SneakersAdapter::JobWrapper], {})
42+
43+
pid = fork { runner.run }
44+
45+
integration_log 'waiting for workers to stabilize (5s).'
46+
sleep 5
47+
48+
yield if block_given?
49+
ensure
50+
Process.kill('TERM', pid) rescue nil
51+
end
52+
53+
it 'runs jobs enqueued on a listening queue' do
54+
start_active_job_workers do
55+
TestJob.perform_later('Hello Rails!')
56+
wait_for_jobs_to_finish
57+
assert_equal @redis.get('rails_active_job').to_i, 1
58+
end
59+
end
60+
61+
it 'scheduling jobs are not supported' do
62+
assert_raises NotImplementedError, 'This queueing backend does not support scheduling jobs.' do
63+
TestJob.set(wait: 1.second).perform_later('Say Hello to Rails later!')
64+
end
65+
end
66+
end

0 commit comments

Comments
 (0)