chasqui 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/README.md +3 -1
- data/chasqui.gemspec +1 -0
- data/examples/full.rb +2 -2
- data/lib/chasqui/multi_broker.rb +25 -17
- data/lib/chasqui/subscription.rb +46 -0
- data/lib/chasqui/version.rb +1 -1
- data/lib/chasqui.rb +36 -31
- data/spec/integration/setup/subscribers.rb +2 -2
- data/spec/lib/chasqui/multi_broker_spec.rb +39 -6
- data/spec/lib/chasqui/subscription_spec.rb +32 -0
- data/spec/lib/chasqui_spec.rb +43 -39
- data/spec/spec_helper.rb +3 -0
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb1a85b1db2129a864d5c04845365d0d27ee155a
|
4
|
+
data.tar.gz: 6391c76b1ab99c388d37d7db0292f524baf14f11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 843753b80abeea5ec7e101dd74208ff14a159f69ca15d77673bc0354e47f85e31c473278209d9a4535eaf674bc37e3522a2cdb5d786e23eea67188220bd39c7d
|
7
|
+
data.tar.gz: e4fe21a58162022da38d9a0e897879f2cf6ac73f8eb1fb54a3807952b0fda0b02ce89869d1fd5bc1af446186ec7ed3fa82635c6c6e01c9851bf65b939d446ad1
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
[](https://travis-ci.org/jbgo/chasqui)
|
2
|
+
[](https://codeclimate.com/github/jbgo/chasqui)
|
3
|
+
[](https://codeclimate.com/github/jbgo/chasqui/coverage)
|
2
4
|
|
3
5
|
# Chasqui
|
4
6
|
|
@@ -86,7 +88,7 @@ Now when you call `Chasqui.publish 'event.name', data, ...`, Chasqui will publis
|
|
86
88
|
|
87
89
|
```rb
|
88
90
|
# file: otherapp/app/subscribers/user_events.rb
|
89
|
-
Chasqui.subscribe
|
91
|
+
Chasqui.subscribe 'com.example.myapp', queue: 'unique_queue_name_for_app' do
|
90
92
|
|
91
93
|
on 'user.sign-up' do |user_id|
|
92
94
|
user = User.find user_id
|
data/chasqui.gemspec
CHANGED
data/examples/full.rb
CHANGED
@@ -28,7 +28,7 @@ Chasqui.configure do |config|
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# file: transcoder/app/subscribers/video_subscriber.rb
|
31
|
-
Chasqui.subscribe
|
31
|
+
Chasqui.subscribe 'com.example.admin', queue: 'transcoder.video' do
|
32
32
|
on 'video.upload' do |video_id|
|
33
33
|
begin
|
34
34
|
Transcorder.transcode video_url(video_id)
|
@@ -41,7 +41,7 @@ Chasqui.subscribe queue: 'transcoder.video', channel: 'com.example.admin' do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
# file: admin/app/subscribers/video_subscriber.rb
|
44
|
-
Chasqui.subscribe
|
44
|
+
Chasqui.subscribe 'com.example.transcoder', queue: 'admin.events' do
|
45
45
|
|
46
46
|
on 'transcoder.video.complete' do |video_id|
|
47
47
|
video = Video.find video_id
|
data/lib/chasqui/multi_broker.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
class Chasqui::MultiBroker < Chasqui::Broker
|
2
4
|
|
3
5
|
def forward_event
|
4
6
|
event = receive or return
|
5
|
-
|
7
|
+
subscriptions = subscriptions_for(event)
|
6
8
|
|
7
9
|
redis.multi do
|
8
|
-
|
9
|
-
dispatch event,
|
10
|
+
subscriptions.each do |subscription_id|
|
11
|
+
dispatch event, subscription_id
|
10
12
|
end
|
11
13
|
redis.rpop(in_progress_queue)
|
12
14
|
end
|
@@ -15,11 +17,23 @@ class Chasqui::MultiBroker < Chasqui::Broker
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def in_progress_queue
|
18
|
-
|
20
|
+
with_namespace inbox, 'in_progress'
|
19
21
|
end
|
20
22
|
|
21
23
|
def inbox_queue
|
22
|
-
|
24
|
+
with_namespace inbox
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_job(queue, event)
|
28
|
+
{
|
29
|
+
class: "Chasqui::#{Chasqui.subscriber_class_name(queue)}",
|
30
|
+
args: [event],
|
31
|
+
queue: 'my-queue',
|
32
|
+
jid: SecureRandom.hex(12),
|
33
|
+
created_at: (event['created_at'] || Time.now).to_f,
|
34
|
+
enqueued_at: Time.now.to_f,
|
35
|
+
retry: !!event['retry']
|
36
|
+
}.to_json
|
23
37
|
end
|
24
38
|
|
25
39
|
private
|
@@ -50,8 +64,8 @@ class Chasqui::MultiBroker < Chasqui::Broker
|
|
50
64
|
end
|
51
65
|
end
|
52
66
|
|
53
|
-
def dispatch(event,
|
54
|
-
backend, queue =
|
67
|
+
def dispatch(event, subscription_id)
|
68
|
+
backend, queue = subscription_id.split('/', 2)
|
55
69
|
job = build_job queue, event
|
56
70
|
|
57
71
|
logger.debug "dispatching event queue=#{queue} backend=#{backend} job=#{job}"
|
@@ -64,18 +78,12 @@ class Chasqui::MultiBroker < Chasqui::Broker
|
|
64
78
|
end
|
65
79
|
end
|
66
80
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
args: [event]
|
71
|
-
}.to_json
|
72
|
-
end
|
73
|
-
|
74
|
-
def subscribers_for(event)
|
75
|
-
redis.smembers to_key('subscribers', event['channel'])
|
81
|
+
def subscriptions_for(event)
|
82
|
+
subscription_key = Chasqui.subscription_key event['channel']
|
83
|
+
redis.smembers with_namespace(subscription_key)
|
76
84
|
end
|
77
85
|
|
78
|
-
def
|
86
|
+
def with_namespace(*args)
|
79
87
|
([redis_namespace] + args).join(':')
|
80
88
|
end
|
81
89
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Chasqui
|
2
|
+
class Subscription
|
3
|
+
attr_reader :queue, :channel, :subscriber_type
|
4
|
+
|
5
|
+
def initialize(queue, channel, subscriber_type=Chasqui::Subscriber)
|
6
|
+
@queue = queue
|
7
|
+
@channel = channel
|
8
|
+
@subscriber_type = subscriber_type
|
9
|
+
end
|
10
|
+
|
11
|
+
def subscription_id
|
12
|
+
queue_name = [worker.namespace, 'queue', queue].compact.join(':')
|
13
|
+
"#{worker_backend}/#{queue_name}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def subscriber
|
17
|
+
@subscriber ||= subscriber_type.new queue, channel
|
18
|
+
end
|
19
|
+
|
20
|
+
def worker
|
21
|
+
# TODO How can we store this in an instance variable without breaking things?
|
22
|
+
case worker_backend
|
23
|
+
when :resque
|
24
|
+
Chasqui::ResqueWorker.create subscriber
|
25
|
+
when :sidekiq
|
26
|
+
Chasqui::SidekiqWorker.create subscriber
|
27
|
+
else
|
28
|
+
raise ConfigurationError.new(
|
29
|
+
"Please choose a supported worker_backend. Choices: #{supported_worker_backends}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def worker_backend
|
36
|
+
Chasqui.config.worker_backend
|
37
|
+
end
|
38
|
+
|
39
|
+
SUPPORTED_WORKER_BACKENDS = [:resque, :sidekiq].freeze
|
40
|
+
|
41
|
+
def supported_worker_backends
|
42
|
+
SUPPORTED_WORKER_BACKENDS.join(', ')
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
data/lib/chasqui/version.rb
CHANGED
data/lib/chasqui.rb
CHANGED
@@ -9,6 +9,7 @@ require "chasqui/config"
|
|
9
9
|
require "chasqui/broker"
|
10
10
|
require "chasqui/multi_broker"
|
11
11
|
require "chasqui/subscriber"
|
12
|
+
require "chasqui/subscription"
|
12
13
|
require "chasqui/workers/worker"
|
13
14
|
require "chasqui/workers/resque_worker"
|
14
15
|
require "chasqui/workers/sidekiq_worker"
|
@@ -28,23 +29,30 @@ module Chasqui
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def publish(event, *args)
|
31
|
-
|
32
|
-
|
32
|
+
redis.lpush inbox_queue, build_payload(event, *args).to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
def subscribe(channel, options={}, &block)
|
36
|
+
queue = options.fetch :queue
|
37
|
+
|
38
|
+
create_subscription(queue, channel).tap do |subscription|
|
39
|
+
subscription.subscriber.evaluate(&block) if block_given?
|
40
|
+
redis.sadd subscription_key(channel), subscription.subscription_id
|
41
|
+
end
|
33
42
|
end
|
34
43
|
|
35
|
-
def
|
44
|
+
def unsubscribe(channel, options={}, &block)
|
36
45
|
queue = options.fetch :queue
|
37
|
-
|
46
|
+
subscription = subscriptions[queue.to_s]
|
38
47
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
redis.sadd "subscribers:#{channel}", subscriber_id(worker, queue)
|
48
|
+
if subscription
|
49
|
+
redis.srem subscription_key(channel), subscription.subscription_id
|
50
|
+
subscription.subscription_id
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
46
|
-
def
|
47
|
-
|
54
|
+
def subscription(queue)
|
55
|
+
subscriptions[queue.to_s]
|
48
56
|
end
|
49
57
|
|
50
58
|
def subscriber_class_name(queue)
|
@@ -52,37 +60,34 @@ module Chasqui
|
|
52
60
|
"Subscriber__#{queue_name_constant}".to_sym
|
53
61
|
end
|
54
62
|
|
55
|
-
def
|
56
|
-
|
57
|
-
when :resque
|
58
|
-
Chasqui::ResqueWorker.create subscriber
|
59
|
-
when :sidekiq
|
60
|
-
Chasqui::SidekiqWorker.create subscriber
|
61
|
-
else
|
62
|
-
raise ConfigurationError.new(
|
63
|
-
"Please choose a supported worker_backend. Choices: #{supported_worker_backends}")
|
64
|
-
end
|
63
|
+
def subscription_key(channel)
|
64
|
+
"subscriptions:#{channel}"
|
65
65
|
end
|
66
66
|
|
67
67
|
private
|
68
68
|
|
69
|
-
def
|
70
|
-
|
71
|
-
"#{config.worker_backend}/#{queue_name}"
|
69
|
+
def create_subscription(queue, channel)
|
70
|
+
subscriptions[queue.to_s] ||= Subscription.new queue, channel
|
72
71
|
end
|
73
72
|
|
74
|
-
def
|
75
|
-
|
73
|
+
def subscriptions
|
74
|
+
@subscriptions ||= {}
|
76
75
|
end
|
77
76
|
|
78
|
-
def
|
79
|
-
|
80
|
-
|
77
|
+
def build_payload(event, *args)
|
78
|
+
opts = extract_job_options!(*args)
|
79
|
+
|
80
|
+
payload = { event: event, channel: channel, data: args }
|
81
|
+
payload[:retry] = opts[:retry] || opts['retry'] if opts
|
82
|
+
payload[:created_at] = Time.now.to_f.to_s
|
81
83
|
|
82
|
-
|
84
|
+
payload
|
85
|
+
end
|
83
86
|
|
84
|
-
def
|
85
|
-
|
87
|
+
def extract_job_options!(*args)
|
88
|
+
if args.last.kind_of?(Hash)
|
89
|
+
args.last.delete(:job_options)
|
90
|
+
end
|
86
91
|
end
|
87
92
|
end
|
88
93
|
end
|
@@ -4,11 +4,11 @@ def log_event subscriber, args
|
|
4
4
|
subscriber.redis.rpush "#{subscriber.queue}:event_log", payload
|
5
5
|
end
|
6
6
|
|
7
|
-
Chasqui.subscribe
|
7
|
+
Chasqui.subscribe 'integration', queue: 'app1' do
|
8
8
|
on('user.signup') { |*args| log_event self, args }
|
9
9
|
end
|
10
10
|
|
11
|
-
Chasqui.subscribe
|
11
|
+
Chasqui.subscribe 'integration', queue: 'app2' do
|
12
12
|
on('account.*') { |*args| log_event self, args }
|
13
13
|
on('user.cancel') { |*args| log_event self, args }
|
14
14
|
end
|
@@ -7,14 +7,15 @@ describe Chasqui::MultiBroker do
|
|
7
7
|
reset_chasqui
|
8
8
|
Chasqui.config.worker_backend = :resque
|
9
9
|
Resque.redis.namespace = nil
|
10
|
+
allow(Time).to receive(:now).and_return(Time.now)
|
10
11
|
end
|
11
12
|
|
12
13
|
describe '#forward_event' do
|
13
14
|
before do
|
14
15
|
Chasqui.config.channel = 'app1'
|
15
|
-
Chasqui.subscribe
|
16
|
-
Chasqui.subscribe
|
17
|
-
Chasqui.subscribe
|
16
|
+
Chasqui.subscribe 'app1', queue: 'queue1'
|
17
|
+
Chasqui.subscribe 'app2', queue: 'queue2'
|
18
|
+
Chasqui.subscribe 'app1', queue: 'queue3'
|
18
19
|
end
|
19
20
|
|
20
21
|
it 'places the event on all subscriber queues' do
|
@@ -27,7 +28,7 @@ describe Chasqui::MultiBroker do
|
|
27
28
|
expect(nnredis.llen('queue:queue2')).to eq(0)
|
28
29
|
expect(nnredis.llen('queue:queue3')).to eq(1)
|
29
30
|
|
30
|
-
event = { 'event' => 'foo.bar', 'channel' => 'app1', 'data' => ['A'] }
|
31
|
+
event = { 'event' => 'foo.bar', 'channel' => 'app1', 'data' => ['A'], 'created_at' => Time.now.to_f.to_s }
|
31
32
|
|
32
33
|
job1 = JSON.parse nnredis.lpop('queue:queue1')
|
33
34
|
expect(job1['args']).to include(event)
|
@@ -48,7 +49,7 @@ describe Chasqui::MultiBroker do
|
|
48
49
|
job = JSON.parse nnredis.blpop('queue:queue2')[1]
|
49
50
|
expect(job).to include('class' => 'Chasqui::Subscriber__queue2')
|
50
51
|
expect(job).to include('args' =>
|
51
|
-
[{ 'event' => 'foo.bar', 'channel' => 'app2', 'data' => ['A'] }])
|
52
|
+
[{ 'event' => 'foo.bar', 'channel' => 'app2', 'data' => ['A'], 'created_at' => Time.now.to_f.to_s }])
|
52
53
|
end
|
53
54
|
ensure
|
54
55
|
thread.kill
|
@@ -71,7 +72,7 @@ describe Chasqui::MultiBroker do
|
|
71
72
|
|
72
73
|
job = JSON.parse nnredis.lpop('queue:queue2')
|
73
74
|
expect(job['args']).to include(
|
74
|
-
'event' => 'foo', 'channel' => 'app2', 'data' => ['process'])
|
75
|
+
'event' => 'foo', 'channel' => 'app2', 'data' => ['process'], 'created_at' => Time.now.to_f.to_s)
|
75
76
|
expect(nnredis.llen(broker.in_progress_queue)).to eq(0)
|
76
77
|
end
|
77
78
|
|
@@ -80,4 +81,36 @@ describe Chasqui::MultiBroker do
|
|
80
81
|
expect(-> { broker.forward_event }).not_to raise_error
|
81
82
|
end
|
82
83
|
end
|
84
|
+
|
85
|
+
describe '#build_job' do
|
86
|
+
it 'includes useful metadata' do
|
87
|
+
event = { 'event' => 'foo', 'channel' => 'bar', 'data' => [] }
|
88
|
+
job = JSON.parse broker.build_job('my-queue', event)
|
89
|
+
|
90
|
+
expect(job['class']).to eq('Chasqui::Subscriber__my_queue')
|
91
|
+
expect(job['args']).to include(event)
|
92
|
+
expect(job['queue']).to eq('my-queue')
|
93
|
+
expect(job['jid']).to match(/^[0-9a-f]{24}/i)
|
94
|
+
expect(job['created_at']).to be_within(0.01).of(Time.now.to_f)
|
95
|
+
expect(job['enqueued_at']).to be_within(0.01).of(Time.now.to_f)
|
96
|
+
expect(job['retry']).to eq(false)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'uses the event created_at time' do
|
100
|
+
created_at = (Time.now - 3).to_f
|
101
|
+
job = JSON.parse broker.build_job('my-queue', 'created_at' => created_at.to_s)
|
102
|
+
expect(job['created_at']).to eq(created_at)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'uses the event retry value' do
|
106
|
+
job = JSON.parse broker.build_job('my-queue', 'retry' => true)
|
107
|
+
expect(job['retry']).to be true
|
108
|
+
|
109
|
+
job = JSON.parse broker.build_job('my-queue', 'retry' => false)
|
110
|
+
expect(job['retry']).to be false
|
111
|
+
|
112
|
+
job = JSON.parse broker.build_job('my-queue', 'retry' => nil)
|
113
|
+
expect(job['retry']).to be false
|
114
|
+
end
|
115
|
+
end
|
83
116
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chasqui::Subscription do
|
4
|
+
|
5
|
+
def new_subscription(queue='default')
|
6
|
+
Chasqui::Subscription.new queue, 'fake-channel', FakeSubscriber
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#worker' do
|
10
|
+
it 'raises when no worker backend configured' do
|
11
|
+
Chasqui.config.worker_backend = nil
|
12
|
+
expect(-> {
|
13
|
+
new_subscription.worker
|
14
|
+
}).to raise_error(Chasqui::ConfigurationError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'creates a resque worker' do
|
18
|
+
Chasqui.config.worker_backend = :resque
|
19
|
+
worker = new_subscription('resque-queue').worker
|
20
|
+
expect(worker.new).to be_kind_of(Chasqui::ResqueWorker)
|
21
|
+
end
|
22
|
+
|
23
|
+
if sidekiq_supported_ruby_version?
|
24
|
+
it 'creates a sidekiq worker' do
|
25
|
+
Chasqui.config.worker_backend = :sidekiq
|
26
|
+
worker = new_subscription('sidekiq-queue').worker
|
27
|
+
expect(worker.new).to be_kind_of(Chasqui::SidekiqWorker)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/spec/lib/chasqui_spec.rb
CHANGED
@@ -111,6 +111,7 @@ describe Chasqui do
|
|
111
111
|
expect(event['event']).to eq('test.event')
|
112
112
|
expect(event['channel']).to eq('__default')
|
113
113
|
expect(event['data']).to eq(data)
|
114
|
+
expect(event['created_at'].to_f).to be_within(0.01).of(Time.now.to_f)
|
114
115
|
end
|
115
116
|
end
|
116
117
|
|
@@ -122,31 +123,11 @@ describe Chasqui do
|
|
122
123
|
expect(event['channel']).to eq('my.app')
|
123
124
|
expect(event['data']).to eq(['foo'])
|
124
125
|
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe '.create_worker' do
|
128
|
-
let(:subscriber) { j }
|
129
|
-
|
130
|
-
it 'raises when no worker backend configured' do
|
131
|
-
expect(-> {
|
132
|
-
Chasqui.create_worker nil
|
133
|
-
}).to raise_error(Chasqui::ConfigurationError)
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'creates a resque worker' do
|
137
|
-
subscriber = FakeSubscriber.new 'resque-queue', 'fake-channel'
|
138
|
-
Chasqui.config.worker_backend = :resque
|
139
|
-
worker = Chasqui.create_worker subscriber
|
140
|
-
expect(worker.new).to be_kind_of(Chasqui::ResqueWorker)
|
141
|
-
end
|
142
126
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
worker = Chasqui.create_worker subscriber
|
148
|
-
expect(worker.new).to be_kind_of(Chasqui::SidekiqWorker)
|
149
|
-
end
|
127
|
+
it 'supports retries' do
|
128
|
+
Chasqui.publish 'test.event', :foo, :bar, foo: 'bar', job_options: { retry: true }
|
129
|
+
event = JSON.load Chasqui.redis.rpop('inbox')
|
130
|
+
expect(event['retry']).to eq(true)
|
150
131
|
end
|
151
132
|
end
|
152
133
|
|
@@ -160,18 +141,18 @@ describe Chasqui do
|
|
160
141
|
before { Resque.redis.namespace = 'blah' }
|
161
142
|
|
162
143
|
it 'creates subscriptions using the appropriate redis namespace' do
|
163
|
-
sub1 = Chasqui.subscribe queue: 'app1-queue'
|
164
|
-
sub2 = Chasqui.subscribe queue: 'app2-queue'
|
165
|
-
sub3 = Chasqui.subscribe queue: 'app1-queue'
|
144
|
+
sub1 = Chasqui.subscribe 'com.example.admin', queue: 'app1-queue'
|
145
|
+
sub2 = Chasqui.subscribe 'com.example.admin', queue: 'app2-queue'
|
146
|
+
sub3 = Chasqui.subscribe 'com.example.video', queue: 'app1-queue'
|
166
147
|
|
167
|
-
queues = Chasqui.redis.smembers "
|
148
|
+
queues = Chasqui.redis.smembers Chasqui.subscription_key("com.example.admin")
|
168
149
|
expect(queues.sort).to eq(['resque/blah:queue:app1-queue', 'resque/blah:queue:app2-queue'])
|
169
150
|
|
170
|
-
queues = Chasqui.redis.smembers "
|
151
|
+
queues = Chasqui.redis.smembers Chasqui.subscription_key("com.example.video")
|
171
152
|
expect(queues).to eq(['resque/blah:queue:app1-queue'])
|
172
153
|
|
173
|
-
expect(Chasqui.
|
174
|
-
expect(Chasqui.
|
154
|
+
expect(Chasqui.subscription('app1-queue')).to eq(sub1)
|
155
|
+
expect(Chasqui.subscription('app2-queue')).to eq(sub2)
|
175
156
|
expect(sub1).to eq(sub3)
|
176
157
|
end
|
177
158
|
end
|
@@ -183,32 +164,55 @@ describe Chasqui do
|
|
183
164
|
end
|
184
165
|
|
185
166
|
it 'creates subscriptions using the appropriate redis namespace' do
|
186
|
-
Chasqui.subscribe queue: 'app1-queue'
|
187
|
-
queues = Chasqui.redis.smembers "
|
167
|
+
Chasqui.subscribe 'com.example.admin', queue: 'app1-queue'
|
168
|
+
queues = Chasqui.redis.smembers Chasqui.subscription_key("com.example.admin")
|
188
169
|
expect(queues.sort).to eq(['sidekiq/queue:app1-queue'])
|
189
170
|
|
190
171
|
Sidekiq.redis = { url: redis.client.options[:url], namespace: 'foobar' }
|
191
|
-
Chasqui.subscribe queue: 'app2-queue'
|
192
|
-
queues = Chasqui.redis.smembers "
|
172
|
+
Chasqui.subscribe 'com.example.video', queue: 'app2-queue'
|
173
|
+
queues = Chasqui.redis.smembers Chasqui.subscription_key("com.example.video")
|
193
174
|
expect(queues.sort).to eq(['sidekiq/foobar:queue:app2-queue'])
|
194
175
|
end
|
195
176
|
end
|
196
177
|
end
|
197
178
|
|
198
|
-
it 'returns a
|
199
|
-
|
200
|
-
expect(subscriber).to be_kind_of(Chasqui::Subscriber)
|
179
|
+
it 'returns a subscription' do
|
180
|
+
subscription = Chasqui.subscribe 'com.example.admin', queue: 'app1-queue'
|
181
|
+
expect(subscription.subscriber).to be_kind_of(Chasqui::Subscriber)
|
201
182
|
end
|
202
183
|
|
203
184
|
it 'yields a subscriber configuration context' do
|
204
185
|
$context = nil
|
205
|
-
Chasqui.subscribe
|
186
|
+
Chasqui.subscribe 'bar', queue: 'foo' do
|
206
187
|
$context = self
|
207
188
|
end
|
208
189
|
expect($context).to be_kind_of(Chasqui::Subscriber)
|
209
190
|
end
|
210
191
|
end
|
211
192
|
|
193
|
+
describe '.unsubscribe' do
|
194
|
+
before do
|
195
|
+
reset_chasqui
|
196
|
+
Chasqui.config.worker_backend = :resque
|
197
|
+
Resque.redis.namespace = 'ns0'
|
198
|
+
Chasqui.subscribe 'com.example.admin', queue: 'app1-queue'
|
199
|
+
Chasqui.subscribe 'com.example.admin', queue: 'app2-queue'
|
200
|
+
Chasqui.subscribe 'com.example.video', queue: 'app1-queue'
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'removes the subscription' do
|
204
|
+
subscription_id = Chasqui.unsubscribe 'com.example.admin', queue: 'app1-queue'
|
205
|
+
expect(subscription_id).to eq('resque/ns0:queue:app1-queue')
|
206
|
+
expect(redis.smembers(Chasqui.subscription_key 'com.example.admin').sort).to eq(['resque/ns0:queue:app2-queue'])
|
207
|
+
expect(redis.smembers(Chasqui.subscription_key 'com.example.video').sort).to eq(['resque/ns0:queue:app1-queue'])
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'returns nil for unknown subscriptions' do
|
211
|
+
subscription_id = Chasqui.unsubscribe 'unknown', queue: 'unknown'
|
212
|
+
expect(subscription_id).to be nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
212
216
|
describe '.subscriber_class_name' do
|
213
217
|
it 'transforms queue name into a subscribe class name' do
|
214
218
|
expect(Chasqui.subscriber_class_name('my-queue')).to eq(:Subscriber__my_queue)
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chasqui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Bach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: codeclimate-test-reporter
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
description:
|
126
140
|
email:
|
127
141
|
- jordan@opensolitude.com
|
@@ -147,6 +161,7 @@ files:
|
|
147
161
|
- lib/chasqui/config.rb
|
148
162
|
- lib/chasqui/multi_broker.rb
|
149
163
|
- lib/chasqui/subscriber.rb
|
164
|
+
- lib/chasqui/subscription.rb
|
150
165
|
- lib/chasqui/version.rb
|
151
166
|
- lib/chasqui/workers/resque_worker.rb
|
152
167
|
- lib/chasqui/workers/sidekiq_worker.rb
|
@@ -162,6 +177,7 @@ files:
|
|
162
177
|
- spec/lib/chasqui/config_spec.rb
|
163
178
|
- spec/lib/chasqui/multi_broker_spec.rb
|
164
179
|
- spec/lib/chasqui/subscriber_spec.rb
|
180
|
+
- spec/lib/chasqui/subscription_spec.rb
|
165
181
|
- spec/lib/chasqui/workers/resque_worker_spec.rb
|
166
182
|
- spec/lib/chasqui/workers/sidekiq_worker_spec.rb
|
167
183
|
- spec/lib/chasqui_spec.rb
|
@@ -208,6 +224,7 @@ test_files:
|
|
208
224
|
- spec/lib/chasqui/config_spec.rb
|
209
225
|
- spec/lib/chasqui/multi_broker_spec.rb
|
210
226
|
- spec/lib/chasqui/subscriber_spec.rb
|
227
|
+
- spec/lib/chasqui/subscription_spec.rb
|
211
228
|
- spec/lib/chasqui/workers/resque_worker_spec.rb
|
212
229
|
- spec/lib/chasqui/workers/sidekiq_worker_spec.rb
|
213
230
|
- spec/lib/chasqui_spec.rb
|
@@ -216,3 +233,4 @@ test_files:
|
|
216
233
|
- spec/support/fake_logger.rb
|
217
234
|
- spec/support/fake_subscriber.rb
|
218
235
|
- spec/support/sidekiq_compatibility_check.rb
|
236
|
+
has_rdoc:
|