chasqui 0.9.3 → 1.0.0.pre.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +60 -39
- data/Vagrantfile +15 -0
- data/lib/chasqui.rb +28 -55
- data/lib/chasqui/broker.rb +3 -3
- data/lib/chasqui/{multi_broker.rb → brokers/redis_broker.rb} +11 -11
- data/lib/chasqui/config.rb +26 -6
- data/lib/chasqui/queue_adapter.rb +14 -0
- data/lib/chasqui/queue_adapters/redis_queue_adapter.rb +51 -0
- data/lib/chasqui/subscriber.rb +56 -49
- data/lib/chasqui/subscriptions.rb +67 -0
- data/lib/chasqui/version.rb +1 -1
- data/lib/chasqui/worker.rb +81 -0
- data/spec/integration/pubsub_examples.rb +20 -20
- data/spec/integration/resque_spec.rb +1 -1
- data/spec/integration/setup/subscribers.rb +25 -9
- data/spec/integration/sidekiq_spec.rb +1 -1
- data/spec/lib/chasqui/{multi_broker_spec.rb → brokers/redis_broker_spec.rb} +54 -26
- data/spec/lib/chasqui/cli_spec.rb +1 -1
- data/spec/lib/chasqui/config_spec.rb +121 -0
- data/spec/lib/chasqui/fake_queue_adapter_spec.rb +5 -0
- data/spec/lib/chasqui/queue_adapters/redis_queue_adapter_spec.rb +73 -0
- data/spec/lib/chasqui/subscriber_spec.rb +95 -43
- data/spec/lib/chasqui/subscriptions_spec.rb +60 -0
- data/spec/lib/chasqui/worker_spec.rb +96 -0
- data/spec/lib/chasqui_spec.rb +32 -191
- data/spec/spec_helper.rb +1 -1
- data/spec/support/chasqui_spec_helpers.rb +28 -0
- data/spec/support/fake_queue_adapter.rb +3 -0
- data/spec/support/fake_subscriber.rb +2 -1
- data/spec/support/shared_examples/queue_adapter_examples.rb +13 -0
- metadata +25 -18
- data/lib/chasqui/subscription.rb +0 -53
- data/lib/chasqui/workers/resque_worker.rb +0 -25
- data/lib/chasqui/workers/sidekiq_worker.rb +0 -45
- data/lib/chasqui/workers/worker.rb +0 -34
- data/spec/lib/chasqui/subscription_spec.rb +0 -35
- data/spec/lib/chasqui/workers/resque_worker_spec.rb +0 -27
- data/spec/lib/chasqui/workers/sidekiq_worker_spec.rb +0 -34
@@ -3,7 +3,7 @@ require 'integration/pubsub_examples'
|
|
3
3
|
|
4
4
|
if sidekiq_supported_ruby_version?
|
5
5
|
describe "sidekiq integration", integration: true do
|
6
|
-
include_examples 'pubsub', :
|
6
|
+
include_examples 'pubsub', :start_sidekiq_workers
|
7
7
|
|
8
8
|
def start_sidekiq_workers
|
9
9
|
@pids << fork do
|
@@ -1,7 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
class Worker1
|
4
|
+
include Chasqui::Subscriber
|
5
|
+
subscribe channel: 'app1', queue: 'queue1'
|
6
|
+
end
|
7
|
+
|
8
|
+
class Worker2
|
9
|
+
include Chasqui::Subscriber
|
10
|
+
subscribe channel: 'app2', queue: 'queue2'
|
11
|
+
end
|
12
|
+
|
13
|
+
class Worker3
|
14
|
+
include Chasqui::Subscriber
|
15
|
+
subscribe channel: 'app1', queue: 'queue3'
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Chasqui::RedisBroker do
|
19
|
+
let(:broker) { Chasqui::RedisBroker.new }
|
5
20
|
|
6
21
|
before do
|
7
22
|
reset_chasqui
|
@@ -12,14 +27,13 @@ describe Chasqui::MultiBroker do
|
|
12
27
|
|
13
28
|
describe '#forward_event' do
|
14
29
|
before do
|
15
|
-
Chasqui.
|
16
|
-
Chasqui.
|
17
|
-
Chasqui.
|
18
|
-
Chasqui.subscribe channel: 'app1', queue: 'queue3'
|
30
|
+
Chasqui.register Worker1
|
31
|
+
Chasqui.register Worker2
|
32
|
+
Chasqui.register Worker3
|
19
33
|
end
|
20
34
|
|
21
35
|
it 'places the event on all subscriber queues' do
|
22
|
-
Chasqui.publish '
|
36
|
+
Chasqui.publish 'app1', foo: 'bar'
|
23
37
|
broker.forward_event
|
24
38
|
|
25
39
|
expect(nnredis.llen(broker.inbox_queue)).to eq(0)
|
@@ -28,7 +42,12 @@ describe Chasqui::MultiBroker do
|
|
28
42
|
expect(nnredis.llen('queue:queue2')).to eq(0)
|
29
43
|
expect(nnredis.llen('queue:queue3')).to eq(1)
|
30
44
|
|
31
|
-
event = {
|
45
|
+
event = {
|
46
|
+
'channel' => 'app1',
|
47
|
+
'payload' => [{ 'foo' => 'bar' }],
|
48
|
+
'created_at' => Time.now.to_f.to_s,
|
49
|
+
'retry' => true
|
50
|
+
}
|
32
51
|
|
33
52
|
job1 = JSON.parse nnredis.lpop('queue:queue1')
|
34
53
|
expect(job1['args']).to include(event)
|
@@ -43,13 +62,19 @@ describe Chasqui::MultiBroker do
|
|
43
62
|
begin
|
44
63
|
Timeout::timeout(1) do
|
45
64
|
Chasqui.config.redis = Redis.new
|
46
|
-
Chasqui.
|
47
|
-
Chasqui.publish 'foo.bar', 'A'
|
65
|
+
Chasqui.publish 'app2', foo: 'bar'
|
48
66
|
|
49
67
|
job = JSON.parse nnredis.blpop('queue:queue2')[1]
|
50
|
-
expect(job).to include('class' => 'Chasqui::
|
51
|
-
|
52
|
-
|
68
|
+
expect(job).to include('class' => 'Chasqui::Workers::Worker2')
|
69
|
+
|
70
|
+
event = {
|
71
|
+
'channel' => 'app2',
|
72
|
+
'payload' => [{ 'foo' => 'bar' }],
|
73
|
+
'created_at' => Time.now.to_f.to_s,
|
74
|
+
'retry' => true
|
75
|
+
}
|
76
|
+
|
77
|
+
expect(job).to include('args' => [event])
|
53
78
|
end
|
54
79
|
ensure
|
55
80
|
thread.kill
|
@@ -57,9 +82,8 @@ describe Chasqui::MultiBroker do
|
|
57
82
|
end
|
58
83
|
|
59
84
|
it "doesn't lose events if the broker fails" do
|
60
|
-
Chasqui.
|
61
|
-
Chasqui.publish '
|
62
|
-
Chasqui.publish 'foo', 'keep in queue'
|
85
|
+
Chasqui.publish 'app2', 'process'
|
86
|
+
Chasqui.publish 'app2', 'keep in queue'
|
63
87
|
allow(broker.redis).to receive(:smembers).and_raise(Redis::ConnectionError)
|
64
88
|
|
65
89
|
expect(-> { broker.forward_event }).to raise_error(Redis::ConnectionError)
|
@@ -72,7 +96,11 @@ describe Chasqui::MultiBroker do
|
|
72
96
|
|
73
97
|
job = JSON.parse nnredis.lpop('queue:queue2')
|
74
98
|
expect(job['args']).to include(
|
75
|
-
'
|
99
|
+
'channel' => 'app2',
|
100
|
+
'payload' => ['process'],
|
101
|
+
'created_at' => Time.now.to_f.to_s,
|
102
|
+
'retry' => true
|
103
|
+
)
|
76
104
|
expect(nnredis.llen(broker.in_progress_queue)).to eq(0)
|
77
105
|
end
|
78
106
|
|
@@ -84,33 +112,33 @@ describe Chasqui::MultiBroker do
|
|
84
112
|
|
85
113
|
describe '#build_job' do
|
86
114
|
it 'includes useful metadata' do
|
87
|
-
event = { '
|
88
|
-
job = JSON.parse broker.build_job('my-queue', event)
|
115
|
+
event = { 'channel' => 'fox4', 'payload' => [] }
|
116
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', event)
|
89
117
|
|
90
|
-
expect(job['class']).to eq('
|
118
|
+
expect(job['class']).to eq('MyWorker')
|
91
119
|
expect(job['args']).to include(event)
|
92
120
|
expect(job['queue']).to eq('my-queue')
|
93
121
|
expect(job['jid']).to match(/^[0-9a-f]{24}/i)
|
94
122
|
expect(job['created_at']).to be_within(0.01).of(Time.now.to_f)
|
95
123
|
expect(job['enqueued_at']).to be_within(0.01).of(Time.now.to_f)
|
96
|
-
expect(job['retry']).to
|
124
|
+
expect(job['retry']).to be nil
|
97
125
|
end
|
98
126
|
|
99
127
|
it 'uses the event created_at time' do
|
100
128
|
created_at = (Time.now - 3).to_f
|
101
|
-
job = JSON.parse broker.build_job('my-queue', 'created_at' => created_at.to_s)
|
129
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', 'created_at' => created_at.to_s)
|
102
130
|
expect(job['created_at']).to eq(created_at)
|
103
131
|
end
|
104
132
|
|
105
133
|
it 'uses the event retry value' do
|
106
|
-
job = JSON.parse broker.build_job('my-queue', 'retry' => true)
|
134
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', 'retry' => true)
|
107
135
|
expect(job['retry']).to be true
|
108
136
|
|
109
|
-
job = JSON.parse broker.build_job('my-queue', 'retry' => false)
|
137
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', 'retry' => false)
|
110
138
|
expect(job['retry']).to be false
|
111
139
|
|
112
|
-
job = JSON.parse broker.build_job('my-queue', 'retry' => nil)
|
113
|
-
expect(job['retry']).to be
|
140
|
+
job = JSON.parse broker.build_job('my-queue', 'MyWorker', 'retry' => nil)
|
141
|
+
expect(job['retry']).to be nil
|
114
142
|
end
|
115
143
|
end
|
116
144
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chasqui::Config do
|
4
|
+
|
5
|
+
context 'defaults' do
|
6
|
+
it { expect(subject.channel_prefix).to be nil }
|
7
|
+
it { expect(subject.default_queue).to eq('chasqui-subscribers') }
|
8
|
+
it { expect(subject.inbox_queue).to eq('inbox') }
|
9
|
+
it { expect(subject.redis.client.db).to eq(0) }
|
10
|
+
it { expect(subject.broker_poll_interval).to eq(3) }
|
11
|
+
it { expect(subject.queue_adapter).to eq(Chasqui::QueueAdapters::RedisQueueAdapter) }
|
12
|
+
|
13
|
+
it do
|
14
|
+
# remove chasqui's test environment logger
|
15
|
+
subject[:logger] = nil
|
16
|
+
expect(subject.logger).to be_kind_of(Logger)
|
17
|
+
end
|
18
|
+
|
19
|
+
it { expect(subject.logger.level).to eq(Logger::INFO) }
|
20
|
+
it { expect(subject.logger.progname).to eq('chasqui') }
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'configures the channel prefix' do
|
24
|
+
subject.channel_prefix = 'com.example.test'
|
25
|
+
expect(subject.channel_prefix).to eq('com.example.test')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'configures the default queue' do
|
29
|
+
subject.default_queue = 'my-app'
|
30
|
+
expect(subject.default_queue).to eq('my-app')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'configures the inbox queue' do
|
34
|
+
subject.inbox_queue = 'foo'
|
35
|
+
expect(subject.inbox_queue).to eq('foo')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'configures the broker poll interval' do
|
39
|
+
subject.broker_poll_interval = 1
|
40
|
+
expect(subject.broker_poll_interval).to eq(1)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'configures the queue adapter' do
|
44
|
+
subject.queue_adapter = FakeQueueAdapter
|
45
|
+
expect(subject.queue_adapter).to eq(FakeQueueAdapter)
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'redis' do
|
49
|
+
it 'accepts config options' do
|
50
|
+
redis_config = { host: '10.0.3.24' }
|
51
|
+
subject.redis = redis_config
|
52
|
+
expect(subject.redis.client.host).to eq('10.0.3.24')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'accepts an initialized client' do
|
56
|
+
redis = Redis.new db: 2
|
57
|
+
subject.redis = redis
|
58
|
+
expect(subject.redis.client.db).to eq(2)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'accepts URLs' do
|
62
|
+
subject.redis = 'redis://10.0.1.21:12345/0'
|
63
|
+
expect(subject.redis.client.host).to eq('10.0.1.21')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'uses a namespace' do
|
67
|
+
subject.redis.set 'foo', 'bar'
|
68
|
+
expect(subject.redis.redis.get 'chasqui:foo').to eq('bar')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'logger' do
|
73
|
+
it 'accepts a log device' do
|
74
|
+
logs = StringIO.new
|
75
|
+
subject.logger = logs
|
76
|
+
subject.logger.info "status"
|
77
|
+
subject.logger.warn "error"
|
78
|
+
|
79
|
+
logs.rewind
|
80
|
+
output = logs.read
|
81
|
+
|
82
|
+
%w(chasqui INFO status WARN error).each do |text|
|
83
|
+
expect(output).to match(text)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'accepts a logger-like object' do
|
88
|
+
fake_logger = FakeLogger.new
|
89
|
+
subject.logger = fake_logger
|
90
|
+
expect(subject.logger).to eq(fake_logger)
|
91
|
+
expect(subject.logger.progname).to eq('chasqui')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'worker_backend' do
|
96
|
+
it 'chooses resque' do
|
97
|
+
allow(Object).to receive(:const_defined?).with(:Resque).and_return true
|
98
|
+
allow(Object).to receive(:const_defined?).with(:Sidekiq).and_return false
|
99
|
+
expect(subject.worker_backend).to eq(:resque)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'chooses sidekiq' do
|
103
|
+
allow(Object).to receive(:const_defined?).with(:Resque).and_return true
|
104
|
+
allow(Object).to receive(:const_defined?).with(:Sidekiq).and_return true
|
105
|
+
expect(subject.worker_backend).to eq(:sidekiq)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'refuses to guess' do
|
109
|
+
allow(Object).to receive(:const_defined?).with(:Resque).and_return false
|
110
|
+
allow(Object).to receive(:const_defined?).with(:Sidekiq).and_return false
|
111
|
+
expect(subject.worker_backend).to be nil
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'allows you to choose the worker backend' do
|
115
|
+
allow(Object).to receive(:const_defined?).with(:Resque).and_return true
|
116
|
+
allow(Object).to receive(:const_defined?).with(:Sidekiq).and_return true
|
117
|
+
subject.worker_backend = :resque
|
118
|
+
expect(subject.worker_backend).to eq(:resque)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MySubscriber
|
4
|
+
include Chasqui::Subscriber
|
5
|
+
subscribe channel: 'channel-name', queue: 'queue-name'
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Chasqui::QueueAdapters::RedisQueueAdapter do
|
9
|
+
it_behaves_like 'a queue adapter'
|
10
|
+
|
11
|
+
let(:subscriber) { MySubscriber }
|
12
|
+
|
13
|
+
describe '#bind / #unbind' do
|
14
|
+
let(:key) { 'subscriptions:channel-name' }
|
15
|
+
|
16
|
+
before { reset_chasqui_workers }
|
17
|
+
after { reset_chasqui_workers }
|
18
|
+
|
19
|
+
context 'resque backend' do
|
20
|
+
before do
|
21
|
+
reset_chasqui
|
22
|
+
Chasqui.config.worker_backend = :resque
|
23
|
+
Resque.redis.namespace = :resque
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'persists the subscriptions to redis' do
|
27
|
+
subject.bind(subscriber)
|
28
|
+
subscriptions = redis.smembers(key)
|
29
|
+
expect(subscriptions).to eq(
|
30
|
+
['resque/Chasqui::Workers::MySubscriber/resque:queue:queue-name'])
|
31
|
+
|
32
|
+
expect(Chasqui::Workers.constants).to include(:MySubscriber)
|
33
|
+
worker = Chasqui::Workers.const_get :MySubscriber
|
34
|
+
expect(worker.subscriber).to eq(MySubscriber)
|
35
|
+
|
36
|
+
redis.sadd key, 'random'
|
37
|
+
|
38
|
+
subject.unbind(subscriber)
|
39
|
+
subscriptions = redis.smembers('subscriptions:channel-name')
|
40
|
+
expect(subscriptions).to eq(['random'])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if sidekiq_supported_ruby_version?
|
45
|
+
context 'sidekiq backend' do
|
46
|
+
before do
|
47
|
+
reset_chasqui
|
48
|
+
Chasqui.config.worker_backend = :sidekiq
|
49
|
+
Sidekiq.configure_client { |c| c.redis = { namespace: nil } }
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'persists the subscription to redis' do
|
53
|
+
subject.bind(subscriber)
|
54
|
+
subscriptions = redis.smembers('subscriptions:channel-name')
|
55
|
+
expect(subscriptions).to eq(
|
56
|
+
['sidekiq/Chasqui::Workers::MySubscriber/queue:queue-name'])
|
57
|
+
expect(redis_no_namespace.smembers 'queues').to eq(['queue-name'])
|
58
|
+
|
59
|
+
expect(Chasqui::Workers.constants).to include(:MySubscriber)
|
60
|
+
worker = Chasqui::Workers.const_get :MySubscriber
|
61
|
+
expect(worker.subscriber).to eq(MySubscriber)
|
62
|
+
|
63
|
+
redis.sadd key, 'random'
|
64
|
+
|
65
|
+
subject.unbind(subscriber)
|
66
|
+
subscriptions = redis.smembers('subscriptions:channel-name')
|
67
|
+
expect(subscriptions).to eq(['random'])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -1,67 +1,119 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Chasqui::Subscriber do
|
4
|
-
let(:
|
4
|
+
let(:subscriber_class) { Class.new { include Chasqui::Subscriber } }
|
5
|
+
let(:redis) { Redis.new }
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
describe '#event' do
|
8
|
+
it { expect(subscriber_class.new(event: 'foo').event).to eq('foo') }
|
9
|
+
it { expect(-> { subscriber_class.new }).to raise_error(KeyError) }
|
10
|
+
end
|
8
11
|
|
9
|
-
describe '#
|
10
|
-
|
11
|
-
subscriber.on('foo') { |foo| foo }
|
12
|
-
subscriber.on('zig.zag') { |*args| args }
|
12
|
+
describe '#redis' do
|
13
|
+
let(:subscriber) { subscriber_class.new event: nil }
|
13
14
|
|
14
|
-
|
15
|
-
expect(subscriber.
|
15
|
+
context 'default' do
|
16
|
+
it { expect(subscriber.redis).to eq(Chasqui.redis) }
|
17
|
+
end
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
+
context 'custom' do
|
20
|
+
let(:redis) { Redis.new }
|
21
|
+
let(:subscriber) { subscriber_class.new event: nil, redis: redis }
|
22
|
+
it { expect(subscriber.redis.object_id).to eq(redis.object_id) }
|
19
23
|
end
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
describe '#logger' do
|
27
|
+
let(:subscriber) { subscriber_class.new event: nil }
|
28
|
+
|
29
|
+
context 'default' do
|
30
|
+
it { expect(subscriber.logger).to eq(Chasqui.logger) }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'custom' do
|
34
|
+
let(:logger) { FakeLogger.new }
|
35
|
+
let(:subscriber) { subscriber_class.new event: nil, logger: logger }
|
36
|
+
it { expect(subscriber.logger).to eq(logger) }
|
26
37
|
end
|
27
38
|
end
|
28
39
|
|
29
|
-
describe '
|
30
|
-
|
31
|
-
expect(
|
40
|
+
describe '.channels' do
|
41
|
+
before do
|
42
|
+
expect(Chasqui).to receive(:register).with(subscriber_class).at_least(:once)
|
43
|
+
subscriber_class.subscribe channel: 'some.channel'
|
32
44
|
end
|
33
45
|
|
34
|
-
|
35
|
-
|
36
|
-
subscriber.on('foo', &p)
|
37
|
-
expect(subscriber.matching_handler_patterns_for('foo')).to eq([/\Afoo\z/])
|
46
|
+
context 'default' do
|
47
|
+
it { expect(subscriber_class.channels).to include('some.channel') }
|
38
48
|
end
|
39
49
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
context 'with default prefix' do
|
51
|
+
before do
|
52
|
+
Chasqui.config.channel_prefix = 'prefix'
|
53
|
+
subscriber_class.subscribe channel: 'some.channel'
|
54
|
+
end
|
55
|
+
|
56
|
+
it { expect(subscriber_class.channels).to include('prefix.some.channel') }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with custom prefix' do
|
60
|
+
before { Chasqui.config.channel_prefix = 'prefix' }
|
61
|
+
|
62
|
+
it 'uses the custom prefix' do
|
63
|
+
subscriber_class.subscribe channel: 'another.channel', prefix: 'custom'
|
64
|
+
expect(subscriber_class.channels).to include('custom.another.channel')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'removes the prefix' do
|
68
|
+
subscriber_class.subscribe channel: 'another.channel', prefix: nil
|
69
|
+
expect(subscriber_class.channels).to include('another.channel')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'multiple channels' do
|
74
|
+
before { subscriber_class.subscribe channel: ['foo', 'bar'], prefix: 'custom' }
|
75
|
+
|
76
|
+
it 'subscribes to multiple channels' do
|
77
|
+
expect(subscriber_class.channels).to eq(['custom.foo', 'custom.bar'])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '.queue' do
|
83
|
+
context 'default' do
|
84
|
+
it { expect(subscriber_class.queue).to eq(Chasqui.default_queue) }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'custom' do
|
88
|
+
before do
|
89
|
+
expect(Chasqui).to receive(:register).with(subscriber_class)
|
90
|
+
subscriber_class.subscribe queue: 'custom-queue'
|
91
|
+
end
|
92
|
+
|
93
|
+
it { expect(subscriber_class.queue).to eq('custom-queue') }
|
54
94
|
end
|
55
95
|
end
|
56
96
|
|
57
97
|
describe '#perform' do
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
98
|
+
let(:subscriber) { subscriber_class.new event: nil }
|
99
|
+
|
100
|
+
it 'is not implemented' do
|
101
|
+
expect(-> {
|
102
|
+
subscriber.perform foo: 'bar'
|
103
|
+
}).to raise_error(NotImplementedError)
|
64
104
|
end
|
65
105
|
end
|
66
106
|
|
107
|
+
describe '.inherited' do
|
108
|
+
before { allow(Chasqui).to receive(:register) }
|
109
|
+
|
110
|
+
it 'maintains a registry of inherited classes' do
|
111
|
+
klass = Class.new do
|
112
|
+
include Chasqui::Subscriber
|
113
|
+
subscribe
|
114
|
+
end
|
115
|
+
|
116
|
+
expect(Chasqui::Subscriber.subscribers).to include(klass)
|
117
|
+
end
|
118
|
+
end
|
67
119
|
end
|