chasqui 1.0.0.pre.rc1 → 1.0.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/.gitignore +1 -0
- data/README.md +90 -78
- data/chasqui.gemspec +1 -1
- data/lib/chasqui.rb +83 -5
- data/lib/chasqui/cli.rb +8 -2
- data/lib/chasqui/config.rb +70 -8
- data/lib/chasqui/{queue_adapters → queue_adapter}/redis_queue_adapter.rb +6 -12
- data/lib/chasqui/subscriber.rb +1 -78
- data/lib/chasqui/subscription_builder.rb +135 -0
- data/lib/chasqui/subscription_builder/resque_subscription_builder.rb +31 -0
- data/lib/chasqui/subscription_builder/sidekiq_subscription_builder.rb +27 -0
- data/lib/chasqui/subscriptions.rb +20 -38
- data/lib/chasqui/version.rb +1 -1
- data/spec/integration/pubsub_examples.rb +1 -0
- data/spec/integration/setup/resque.rb +38 -1
- data/spec/integration/setup/sidekiq.rb +40 -1
- data/spec/lib/chasqui/brokers/redis_broker_spec.rb +12 -10
- data/spec/lib/chasqui/config_spec.rb +3 -3
- data/spec/lib/chasqui/{queue_adapters → queue_adapter}/redis_queue_adapter_spec.rb +6 -19
- data/spec/lib/chasqui/subscriber_spec.rb +4 -114
- data/spec/lib/chasqui/subscription_builder/resque_subscription_builder_spec.rb +20 -0
- data/spec/lib/chasqui/subscription_builder/sidekiq_subscription_builder_spec.rb +27 -0
- data/spec/lib/chasqui/subscription_builder_spec.rb +41 -0
- data/spec/lib/chasqui/subscriptions_spec.rb +4 -4
- data/spec/lib/chasqui_spec.rb +76 -12
- data/spec/support/chasqui_spec_helpers.rb +0 -21
- data/spec/support/fake_worker.rb +2 -0
- data/spec/support/shared_examples/subscription_builder_examples.rb +99 -0
- metadata +22 -16
- data/lib/chasqui/worker.rb +0 -81
- data/spec/integration/setup/subscribers.rb +0 -30
- data/spec/lib/chasqui/worker_spec.rb +0 -96
- data/spec/support/fake_subscriber.rb +0 -13
@@ -13,8 +13,6 @@ module ChasquiSpecHelpers
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def reset_chasqui_workers
|
16
|
-
Chasqui::Worker.workers.clear
|
17
|
-
|
18
16
|
Chasqui::Workers.constants.each do |c|
|
19
17
|
Chasqui::Workers.send :remove_const, c
|
20
18
|
end
|
@@ -32,23 +30,4 @@ module ChasquiSpecHelpers
|
|
32
30
|
def flush_redis
|
33
31
|
nnredis.keys('*').each { |k| nnredis.del k }
|
34
32
|
end
|
35
|
-
|
36
|
-
def new_subscriber(class_name, options={})
|
37
|
-
queue = options.fetch :queue
|
38
|
-
channel = options.fetch :channel
|
39
|
-
|
40
|
-
@subscriber_registry ||= {}
|
41
|
-
|
42
|
-
if @subscriber_registry[class_name] && options[:force]
|
43
|
-
Object.send :remove_const, class_name
|
44
|
-
@subscriber_registry[class_name] = nil
|
45
|
-
end
|
46
|
-
|
47
|
-
@subscriber_registry[class_name] ||= Class.new
|
48
|
-
|
49
|
-
@subscriber_registry[class_name].tap do |sub|
|
50
|
-
sub.send :include, Chasqui::Subscriber
|
51
|
-
sub.subscribe channel: channel, queue: queue
|
52
|
-
end
|
53
|
-
end
|
54
33
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
shared_examples 'a subscription builder' do |worker|
|
2
|
+
before { reset_chasqui_workers }
|
3
|
+
|
4
|
+
# hook for any backend specific assertions on the generated worker class
|
5
|
+
# for a proc
|
6
|
+
def expect_worker_to_support_backend(worker)
|
7
|
+
# noop
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#on' do
|
11
|
+
let(:channel) { 'busy.channel' }
|
12
|
+
let(:queue) { 'pubsub' }
|
13
|
+
|
14
|
+
let(:subscriptions) { double }
|
15
|
+
|
16
|
+
let(:builder) { described_class.new subscriptions }
|
17
|
+
|
18
|
+
it 'subscribes the worker to the channel' do
|
19
|
+
expect(subscriptions).to receive(:register) do |subscriber|
|
20
|
+
expect(subscriber.channel).to eq(channel)
|
21
|
+
expect(subscriber.worker).to eq(worker)
|
22
|
+
expect(subscriber.queue).to eq(queue)
|
23
|
+
end
|
24
|
+
|
25
|
+
builder.on channel, worker
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'prefixes the queue name' do
|
29
|
+
full_queue_name = "app_id:#{queue}"
|
30
|
+
|
31
|
+
expect(subscriptions).to receive(:register) do |subscriber|
|
32
|
+
expect(subscriber.channel).to eq(channel)
|
33
|
+
expect(subscriber.worker).to eq(worker)
|
34
|
+
expect(subscriber.queue).to eq(full_queue_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
builder.on channel, worker, queue_prefix: 'app_id'
|
38
|
+
|
39
|
+
expect(queue_name(worker)).to eq(full_queue_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'uses a different queue' do
|
43
|
+
expect(subscriptions).to receive(:register) do |subscriber|
|
44
|
+
expect(subscriber.channel).to eq(channel)
|
45
|
+
expect(subscriber.worker).to eq(worker)
|
46
|
+
expect(subscriber.queue).to eq('other:queue')
|
47
|
+
end
|
48
|
+
|
49
|
+
builder.on channel, worker, queue: 'other:queue'
|
50
|
+
|
51
|
+
expect(queue_name(worker)).to eq('other:queue')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does something expected when both options are used' do
|
55
|
+
expect(subscriptions).to receive(:register) do |subscriber|
|
56
|
+
expect(subscriber.channel).to eq(channel)
|
57
|
+
expect(subscriber.worker).to eq(worker)
|
58
|
+
expect(subscriber.queue).to eq('prefix:other:queue')
|
59
|
+
end
|
60
|
+
|
61
|
+
builder.on channel, worker, queue: 'other:queue', queue_prefix: 'prefix'
|
62
|
+
|
63
|
+
expect(queue_name(worker)).to eq('prefix:other:queue')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'converts a proc to a worker' do
|
67
|
+
expect(subscriptions).to receive(:register) do |subscriber|
|
68
|
+
queue = "app_id:#{Chasqui.default_queue}"
|
69
|
+
|
70
|
+
expect(subscriber.channel).to eq('busy.channel')
|
71
|
+
expect(subscriber.queue).to eq(queue)
|
72
|
+
|
73
|
+
worker = subscriber.worker
|
74
|
+
expect(worker.name).to eq('Chasqui::Workers::BusyChannelWorker')
|
75
|
+
expect(queue_name(worker)).to eq(queue)
|
76
|
+
|
77
|
+
event = { 'payload' => [3] }
|
78
|
+
expect(perform(worker, event)).to eq(6)
|
79
|
+
expect_worker_to_support_backend(worker)
|
80
|
+
end
|
81
|
+
|
82
|
+
builder.on channel, ->(event, x) { x + x }, queue_prefix: 'app_id'
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'default options' do
|
86
|
+
let(:builder) do
|
87
|
+
described_class.new subscriptions, queue_prefix: 'unique', queue: 'low-priority'
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'uses options supplied during initialization when not supplied to #on' do
|
91
|
+
expect(subscriptions).to receive(:register) do |subscriber|
|
92
|
+
expect(subscriber.queue).to eq('unique:high-priority')
|
93
|
+
end
|
94
|
+
|
95
|
+
builder.on channel, worker, queue: 'high-priority'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
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: 1.0.0
|
4
|
+
version: 1.0.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-12-
|
11
|
+
date: 2015-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -164,33 +164,37 @@ files:
|
|
164
164
|
- lib/chasqui/cli.rb
|
165
165
|
- lib/chasqui/config.rb
|
166
166
|
- lib/chasqui/queue_adapter.rb
|
167
|
-
- lib/chasqui/
|
167
|
+
- lib/chasqui/queue_adapter/redis_queue_adapter.rb
|
168
168
|
- lib/chasqui/subscriber.rb
|
169
|
+
- lib/chasqui/subscription_builder.rb
|
170
|
+
- lib/chasqui/subscription_builder/resque_subscription_builder.rb
|
171
|
+
- lib/chasqui/subscription_builder/sidekiq_subscription_builder.rb
|
169
172
|
- lib/chasqui/subscriptions.rb
|
170
173
|
- lib/chasqui/version.rb
|
171
|
-
- lib/chasqui/worker.rb
|
172
174
|
- spec/integration/pubsub_examples.rb
|
173
175
|
- spec/integration/resque_spec.rb
|
174
176
|
- spec/integration/setup/resque.rb
|
175
177
|
- spec/integration/setup/sidekiq.rb
|
176
|
-
- spec/integration/setup/subscribers.rb
|
177
178
|
- spec/integration/sidekiq_spec.rb
|
178
179
|
- spec/lib/chasqui/broker_spec.rb
|
179
180
|
- spec/lib/chasqui/brokers/redis_broker_spec.rb
|
180
181
|
- spec/lib/chasqui/cli_spec.rb
|
181
182
|
- spec/lib/chasqui/config_spec.rb
|
182
183
|
- spec/lib/chasqui/fake_queue_adapter_spec.rb
|
183
|
-
- spec/lib/chasqui/
|
184
|
+
- spec/lib/chasqui/queue_adapter/redis_queue_adapter_spec.rb
|
184
185
|
- spec/lib/chasqui/subscriber_spec.rb
|
186
|
+
- spec/lib/chasqui/subscription_builder/resque_subscription_builder_spec.rb
|
187
|
+
- spec/lib/chasqui/subscription_builder/sidekiq_subscription_builder_spec.rb
|
188
|
+
- spec/lib/chasqui/subscription_builder_spec.rb
|
185
189
|
- spec/lib/chasqui/subscriptions_spec.rb
|
186
|
-
- spec/lib/chasqui/worker_spec.rb
|
187
190
|
- spec/lib/chasqui_spec.rb
|
188
191
|
- spec/spec_helper.rb
|
189
192
|
- spec/support/chasqui_spec_helpers.rb
|
190
193
|
- spec/support/fake_logger.rb
|
191
194
|
- spec/support/fake_queue_adapter.rb
|
192
|
-
- spec/support/
|
195
|
+
- spec/support/fake_worker.rb
|
193
196
|
- spec/support/shared_examples/queue_adapter_examples.rb
|
197
|
+
- spec/support/shared_examples/subscription_builder_examples.rb
|
194
198
|
- spec/support/sidekiq_compatibility_check.rb
|
195
199
|
- tmp/.keep
|
196
200
|
homepage: https://github.com/jbgo/chasqui
|
@@ -208,37 +212,39 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
208
212
|
version: '0'
|
209
213
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
210
214
|
requirements:
|
211
|
-
- - "
|
215
|
+
- - ">="
|
212
216
|
- !ruby/object:Gem::Version
|
213
|
-
version:
|
217
|
+
version: '0'
|
214
218
|
requirements: []
|
215
219
|
rubyforge_project:
|
216
220
|
rubygems_version: 2.4.5.1
|
217
221
|
signing_key:
|
218
222
|
specification_version: 4
|
219
|
-
summary: Chasqui
|
220
|
-
|
223
|
+
summary: Chasqui adds persistent publish-subscribe (pub-sub) messaging capabilities
|
224
|
+
to Sidekiq and Resque workers.
|
221
225
|
test_files:
|
222
226
|
- spec/integration/pubsub_examples.rb
|
223
227
|
- spec/integration/resque_spec.rb
|
224
228
|
- spec/integration/setup/resque.rb
|
225
229
|
- spec/integration/setup/sidekiq.rb
|
226
|
-
- spec/integration/setup/subscribers.rb
|
227
230
|
- spec/integration/sidekiq_spec.rb
|
228
231
|
- spec/lib/chasqui/broker_spec.rb
|
229
232
|
- spec/lib/chasqui/brokers/redis_broker_spec.rb
|
230
233
|
- spec/lib/chasqui/cli_spec.rb
|
231
234
|
- spec/lib/chasqui/config_spec.rb
|
232
235
|
- spec/lib/chasqui/fake_queue_adapter_spec.rb
|
233
|
-
- spec/lib/chasqui/
|
236
|
+
- spec/lib/chasqui/queue_adapter/redis_queue_adapter_spec.rb
|
234
237
|
- spec/lib/chasqui/subscriber_spec.rb
|
238
|
+
- spec/lib/chasqui/subscription_builder/resque_subscription_builder_spec.rb
|
239
|
+
- spec/lib/chasqui/subscription_builder/sidekiq_subscription_builder_spec.rb
|
240
|
+
- spec/lib/chasqui/subscription_builder_spec.rb
|
235
241
|
- spec/lib/chasqui/subscriptions_spec.rb
|
236
|
-
- spec/lib/chasqui/worker_spec.rb
|
237
242
|
- spec/lib/chasqui_spec.rb
|
238
243
|
- spec/spec_helper.rb
|
239
244
|
- spec/support/chasqui_spec_helpers.rb
|
240
245
|
- spec/support/fake_logger.rb
|
241
246
|
- spec/support/fake_queue_adapter.rb
|
242
|
-
- spec/support/
|
247
|
+
- spec/support/fake_worker.rb
|
243
248
|
- spec/support/shared_examples/queue_adapter_examples.rb
|
249
|
+
- spec/support/shared_examples/subscription_builder_examples.rb
|
244
250
|
- spec/support/sidekiq_compatibility_check.rb
|
data/lib/chasqui/worker.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
module Chasqui
|
2
|
-
module Chasqui::Workers
|
3
|
-
end
|
4
|
-
|
5
|
-
class Worker
|
6
|
-
class << self
|
7
|
-
|
8
|
-
BACKENDS = {
|
9
|
-
resque: 'ResqueWorkerFactory',
|
10
|
-
sidekiq: 'SidekiqWorkerFactory'
|
11
|
-
}
|
12
|
-
|
13
|
-
def create(subscriber)
|
14
|
-
workers[subscriber.object_id] ||= create_worker(subscriber)
|
15
|
-
end
|
16
|
-
|
17
|
-
def workers
|
18
|
-
@workers ||= {}
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def check_for_worker_backend
|
24
|
-
unless BACKENDS.keys.include? Chasqui.worker_backend
|
25
|
-
msg = "Chasqui.config.worker_backend must be one of #{BACKENDS.keys}"
|
26
|
-
raise ConfigurationError.new msg
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def worker_factory
|
31
|
-
Chasqui.const_get BACKENDS[Chasqui.worker_backend]
|
32
|
-
end
|
33
|
-
|
34
|
-
def create_worker(subscriber)
|
35
|
-
check_for_worker_backend
|
36
|
-
worker = worker_factory.create subscriber
|
37
|
-
Chasqui::Workers.const_set subscriber.name, worker
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
class ResqueWorkerFactory
|
44
|
-
def self.create(subscriber)
|
45
|
-
Class.new do
|
46
|
-
@queue = subscriber.queue
|
47
|
-
@subscriber = subscriber
|
48
|
-
|
49
|
-
class << self
|
50
|
-
attr_reader :subscriber
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.perform(event)
|
54
|
-
instance = @subscriber.new event: event, logger: Resque.logger
|
55
|
-
instance.perform event['payload']
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
class SidekiqWorkerFactory
|
62
|
-
def self.create(subscriber)
|
63
|
-
Class.new do
|
64
|
-
include Sidekiq::Worker
|
65
|
-
sidekiq_options 'queue' => 'foo-queue'
|
66
|
-
|
67
|
-
@subscriber = subscriber
|
68
|
-
|
69
|
-
class << self
|
70
|
-
attr_reader :subscriber
|
71
|
-
end
|
72
|
-
|
73
|
-
def perform(event)
|
74
|
-
instance = self.class.subscriber.new event: event, logger: logger
|
75
|
-
instance.perform event['payload']
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
def log_event subscriber, payload
|
2
|
-
Chasqui.redis.rpush "#{subscriber.class.queue}:event_log", subscriber.event.to_json
|
3
|
-
end
|
4
|
-
|
5
|
-
class UserSignupSubscriber
|
6
|
-
include Chasqui::Subscriber
|
7
|
-
subscribe channel: 'user.signup', queue: 'app1'
|
8
|
-
|
9
|
-
def perform(payload)
|
10
|
-
log_event self, payload
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class AccountSubscriber
|
15
|
-
include Chasqui::Subscriber
|
16
|
-
subscribe channel: ['account.credit', 'account.debit'], queue: 'app2'
|
17
|
-
|
18
|
-
def perform(payload)
|
19
|
-
log_event self, payload
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class UserCancelSubscriber
|
24
|
-
include Chasqui::Subscriber
|
25
|
-
subscribe channel: 'user.cancel', queue: 'app2'
|
26
|
-
|
27
|
-
def perform(payload)
|
28
|
-
log_event self, payload
|
29
|
-
end
|
30
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class MockSubscriber
|
4
|
-
include Chasqui::Subscriber
|
5
|
-
subscribe channel: 'foo-channel', prefix: nil, queue: 'foo-queue'
|
6
|
-
|
7
|
-
def perform(payload)
|
8
|
-
self.class.info[:event] = event
|
9
|
-
self.class.info[:payload] = payload
|
10
|
-
self.class.info[:redis] = redis
|
11
|
-
self.class.info[:logger] = logger
|
12
|
-
end
|
13
|
-
|
14
|
-
class << self
|
15
|
-
def info
|
16
|
-
@info ||= {}
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe Chasqui::Worker do
|
22
|
-
before do
|
23
|
-
reset_config
|
24
|
-
Chasqui::Worker.workers.clear
|
25
|
-
MockSubscriber.instance_variable_set :@info, nil
|
26
|
-
end
|
27
|
-
|
28
|
-
let(:subscriber) { MockSubscriber }
|
29
|
-
|
30
|
-
context 'no worker backend' do
|
31
|
-
describe '.create' do
|
32
|
-
it 'raises' do
|
33
|
-
Chasqui.config.worker_backend = :does_not_exist
|
34
|
-
|
35
|
-
expect(-> {
|
36
|
-
Chasqui::Worker.create subscriber
|
37
|
-
}).to raise_error(Chasqui::ConfigurationError)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context 'resque' do
|
43
|
-
before { Chasqui.config.worker_backend = :resque }
|
44
|
-
after { Chasqui::Workers.send :remove_const, :MockSubscriber }
|
45
|
-
|
46
|
-
describe '.create' do
|
47
|
-
let(:worker) { Chasqui::Worker.create subscriber }
|
48
|
-
|
49
|
-
it { expect(worker.name).to eq('Chasqui::Workers::MockSubscriber') }
|
50
|
-
it { expect(worker.instance_variable_get(:@queue)).to eq(subscriber.queue) }
|
51
|
-
it { expect(worker.instance_variable_get(:@subscriber)).to eq(subscriber) }
|
52
|
-
|
53
|
-
it 'delegates #perform to the subscriber' do
|
54
|
-
event = {
|
55
|
-
'channel' => 'foo-channel',
|
56
|
-
'payload' => { 'some' => 'data' }
|
57
|
-
}
|
58
|
-
|
59
|
-
worker.perform event
|
60
|
-
|
61
|
-
expect(subscriber.info[:event]).to eq(event)
|
62
|
-
expect(subscriber.info[:payload]).to eq(event['payload'])
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
if sidekiq_supported_ruby_version?
|
68
|
-
context 'sidekiq' do
|
69
|
-
before { Chasqui.config.worker_backend = :sidekiq }
|
70
|
-
after { Chasqui::Workers.send :remove_const, :MockSubscriber }
|
71
|
-
|
72
|
-
describe '.create' do
|
73
|
-
let(:worker) { Chasqui::Worker.create subscriber }
|
74
|
-
|
75
|
-
it { expect(worker.name).to eq('Chasqui::Workers::MockSubscriber') }
|
76
|
-
it { expect(worker.instance_variable_get(:@subscriber)).to eq(subscriber) }
|
77
|
-
it { expect(worker.sidekiq_options).to include('queue' => 'foo-queue') }
|
78
|
-
it { expect(worker.included_modules).to include(Sidekiq::Worker) }
|
79
|
-
|
80
|
-
it 'delegates #perform to the subscriber' do
|
81
|
-
event = {
|
82
|
-
'channel' => 'foo-channel',
|
83
|
-
'payload' => { 'some' => 'data' }
|
84
|
-
}
|
85
|
-
|
86
|
-
sidekiq_worker = worker.new
|
87
|
-
sidekiq_worker.perform event
|
88
|
-
|
89
|
-
expect(subscriber.info[:event]).to eq(event)
|
90
|
-
expect(subscriber.info[:payload]).to eq(event['payload'])
|
91
|
-
expect(subscriber.info[:logger]).to eq(sidekiq_worker.logger)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|