queue-bus 0.8.0 → 0.11.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +21 -0
  3. data/CHANGELOG.md +31 -0
  4. data/Gemfile +4 -2
  5. data/README.mdown +15 -3
  6. data/Rakefile +2 -0
  7. data/lib/queue-bus.rb +16 -12
  8. data/lib/queue_bus/adapters/base.rb +4 -2
  9. data/lib/queue_bus/adapters/data.rb +12 -11
  10. data/lib/queue_bus/application.rb +24 -16
  11. data/lib/queue_bus/config.rb +23 -2
  12. data/lib/queue_bus/dispatch.rb +14 -12
  13. data/lib/queue_bus/dispatchers.rb +12 -5
  14. data/lib/queue_bus/driver.rb +15 -10
  15. data/lib/queue_bus/heartbeat.rb +32 -30
  16. data/lib/queue_bus/local.rb +9 -9
  17. data/lib/queue_bus/matcher.rb +36 -27
  18. data/lib/queue_bus/publisher.rb +7 -5
  19. data/lib/queue_bus/publishing.rb +32 -24
  20. data/lib/queue_bus/rider.rb +26 -22
  21. data/lib/queue_bus/subscriber.rb +20 -14
  22. data/lib/queue_bus/subscription.rb +25 -15
  23. data/lib/queue_bus/subscription_list.rb +30 -12
  24. data/lib/queue_bus/task_manager.rb +25 -16
  25. data/lib/queue_bus/tasks.rb +35 -11
  26. data/lib/queue_bus/util.rb +11 -8
  27. data/lib/queue_bus/version.rb +3 -1
  28. data/lib/queue_bus/worker.rb +3 -2
  29. data/queue-bus.gemspec +19 -18
  30. data/spec/adapter/publish_at_spec.rb +28 -25
  31. data/spec/adapter/support.rb +7 -1
  32. data/spec/adapter_spec.rb +4 -2
  33. data/spec/application_spec.rb +138 -96
  34. data/spec/config_spec.rb +36 -0
  35. data/spec/dispatch_spec.rb +48 -51
  36. data/spec/driver_spec.rb +60 -58
  37. data/spec/heartbeat_spec.rb +26 -24
  38. data/spec/integration_spec.rb +41 -40
  39. data/spec/matcher_spec.rb +104 -102
  40. data/spec/publish_spec.rb +68 -46
  41. data/spec/publisher_spec.rb +3 -1
  42. data/spec/rider_spec.rb +16 -14
  43. data/spec/spec_helper.rb +2 -2
  44. data/spec/subscriber_spec.rb +227 -227
  45. data/spec/subscription_list_spec.rb +57 -31
  46. data/spec/subscription_spec.rb +37 -36
  47. data/spec/worker_spec.rb +17 -15
  48. metadata +12 -10
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module QueueBus
2
- VERSION = "0.8.0"
4
+ VERSION = '0.11.0'
3
5
  end
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module QueueBus
2
4
  class Worker
3
-
4
5
  def self.perform(json)
5
6
  klass = nil
6
7
  attributes = ::QueueBus::Util.decode(json)
7
8
  begin
8
- class_name = attributes["bus_class_proxy"]
9
+ class_name = attributes['bus_class_proxy']
9
10
  klass = ::QueueBus::Util.constantize(class_name)
10
11
  rescue NameError
11
12
  # not there anymore
data/queue-bus.gemspec CHANGED
@@ -1,33 +1,34 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "queue_bus/version"
1
+ # frozen_string_literal: true
2
+
3
+ $:.push File.expand_path('lib', __dir__)
4
+ require 'queue_bus/version'
4
5
 
5
6
  Gem::Specification.new do |s|
6
- s.name = "queue-bus"
7
+ s.name = 'queue-bus'
7
8
  s.version = QueueBus::VERSION
8
- s.authors = ["Brian Leonard"]
9
- s.email = ["brian@bleonard.com"]
10
- s.homepage = ""
11
- s.summary = %q{A simple event bus on top of background queues}
12
- s.description = %q{A simple event bus on top of common background queues. Publish and subscribe to events as they occur using what you already have.}
9
+ s.authors = ['Brian Leonard']
10
+ s.email = ['brian@bleonard.com']
11
+ s.homepage = ''
12
+ s.summary = 'A simple event bus on top of background queues'
13
+ s.description = 'A simple event bus on top of common background queues. Publish and subscribe to events as they occur using what you already have.'
13
14
 
14
- s.rubyforge_project = "queue-bus"
15
+ s.rubyforge_project = 'queue-bus'
15
16
 
16
17
  s.files = `git ls-files`.split("\n")
17
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- s.require_paths = ["lib"]
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
20
+ s.require_paths = ['lib']
20
21
 
21
- s.add_dependency("multi_json")
22
- s.add_dependency("redis")
22
+ s.add_dependency('multi_json')
23
+ s.add_dependency('redis')
23
24
 
24
25
  # if using resque
25
26
  # s.add_development_dependency('resque', ['>= 1.10.0', '< 2.0'])
26
27
  # s.add_development_dependency('resque-scheduler', '>= 2.0.1')
27
28
  # s.add_development_dependency('resque-retry')
28
29
 
29
- s.add_development_dependency("rspec")
30
- s.add_development_dependency("timecop")
31
- s.add_development_dependency("json_pure")
32
- s.add_development_dependency("rubocop")
30
+ s.add_development_dependency('json_pure')
31
+ s.add_development_dependency('rspec')
32
+ s.add_development_dependency('rubocop')
33
+ s.add_development_dependency('timecop')
33
34
  end
@@ -1,51 +1,54 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- describe "Publishing an event in the future" do
3
+ require 'spec_helper'
4
4
 
5
+ describe 'Publishing an event in the future' do
5
6
  before(:each) do
6
7
  Timecop.freeze(now)
7
- allow(QueueBus).to receive(:generate_uuid).and_return("idfhlkj")
8
+ allow(QueueBus).to receive(:generate_uuid).and_return('idfhlkj')
8
9
  end
9
10
  after(:each) do
10
11
  Timecop.return
11
12
  end
12
- let(:delayed_attrs) { {
13
- "bus_delayed_until" => future.to_i,
14
- "bus_id" => "#{now.to_i}-idfhlkj",
15
- "bus_app_hostname" => `hostname 2>&1`.strip.sub(/.local/,'')} }
13
+ let(:delayed_attrs) do
14
+ {
15
+ 'bus_delayed_until' => future.to_i,
16
+ 'bus_id' => "#{now.to_i}-idfhlkj",
17
+ 'bus_app_hostname' => `hostname 2>&1`.strip.sub(/.local/, '')
18
+ }
19
+ end
16
20
 
17
- let(:bus_attrs) { delayed_attrs.merge({"bus_published_at" => worktime.to_i})}
18
- let(:now) { Time.parse("01/01/2013 5:00")}
21
+ let(:bus_attrs) { delayed_attrs.merge('bus_published_at' => worktime.to_i) }
22
+ let(:now) { Time.parse('01/01/2013 5:00') }
19
23
  let(:future) { Time.at(now.to_i + 60) }
20
- let(:worktime) {Time.at(future.to_i + 1)}
24
+ let(:worktime) { Time.at(future.to_i + 1) }
21
25
 
22
- it "should add it to Redis then to the real queue" do
23
- hash = {:one => 1, "two" => "here", "id" => 12 }
24
- event_name = "event_name"
26
+ it 'should add it to Redis then to the real queue' do
27
+ hash = { :one => 1, 'two' => 'here', 'id' => 12 }
28
+ event_name = 'event_name'
25
29
  QueueBus.publish_at(future, event_name, hash)
26
30
 
27
- schedule = QueueBus.redis { |redis| redis.zrange("delayed_queue_schedule", 0, 1) }
31
+ schedule = QueueBus.redis { |redis| redis.zrange('delayed_queue_schedule', 0, 1) }
28
32
  expect(schedule).to eq([future.to_i.to_s])
29
33
 
30
34
  val = QueueBus.redis { |redis| redis.lpop("delayed:#{future.to_i}") }
31
35
  hash = JSON.parse(val)
32
36
 
33
- expect(hash["class"]).to eq("QueueBus::Worker")
34
- expect(hash["args"].size).to eq(1)
35
- expect(JSON.parse(hash["args"].first)).to eq({"bus_class_proxy"=>"QueueBus::Publisher", "bus_event_type"=>"event_name", "two"=>"here", "one"=>1, "id" => 12}.merge(delayed_attrs))
36
- expect(hash["queue"]).to eq("bus_incoming")
37
+ expect(hash['class']).to eq('QueueBus::Worker')
38
+ expect(hash['args'].size).to eq(1)
39
+ expect(JSON.parse(hash['args'].first)).to eq({ 'bus_class_proxy' => 'QueueBus::Publisher', 'bus_event_type' => 'event_name', 'two' => 'here', 'one' => 1, 'id' => 12 }.merge(delayed_attrs))
40
+ expect(hash['queue']).to eq('bus_incoming')
37
41
 
38
- val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
42
+ val = QueueBus.redis { |redis| redis.lpop('queue:bus_incoming') }
39
43
  expect(val).to eq(nil) # nothing really added
40
44
 
41
45
  Timecop.freeze(worktime)
42
- QueueBus::Publisher.perform(JSON.parse(hash["args"].first))
46
+ QueueBus::Publisher.perform(JSON.parse(hash['args'].first))
43
47
 
44
- val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
48
+ val = QueueBus.redis { |redis| redis.lpop('queue:bus_incoming') }
45
49
  hash = JSON.parse(val)
46
- expect(hash["class"]).to eq("QueueBus::Worker")
47
- expect(hash["args"].size).to eq(1)
48
- expect(JSON.parse(hash["args"].first)).to eq({"bus_class_proxy"=>"QueueBus::Driver", "bus_event_type"=>"event_name", "two"=>"here", "one"=>1, "id" => 12}.merge(bus_attrs))
50
+ expect(hash['class']).to eq('QueueBus::Worker')
51
+ expect(hash['args'].size).to eq(1)
52
+ expect(JSON.parse(hash['args'].first)).to eq({ 'bus_class_proxy' => 'QueueBus::Driver', 'bus_event_type' => 'event_name', 'two' => 'here', 'one' => 1, 'id' => 12 }.merge(bus_attrs))
49
53
  end
50
-
51
54
  end
@@ -1,9 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'redis'
2
4
 
3
5
  def reset_test_adapter
4
6
  QueueBus.send(:reset)
5
7
  QueueBus.adapter = :data
6
- QueueBus.adapter.redis = Redis.new
8
+ QueueBus.adapter.redis = if ENV['REDIS_URL']
9
+ Redis.new(url: ENV['REDIS_URL'])
10
+ else
11
+ Redis.new
12
+ end
7
13
  end
8
14
 
9
15
  def adapter_under_test_class
data/spec/adapter_spec.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
- describe "adapter is set" do
5
+ describe 'adapter is set' do
4
6
  it "should call it's enabled! method on init" do
5
7
  QueueBus.send(:reset)
6
8
  expect_any_instance_of(adapter_under_test_class).to receive(:enabled!)
@@ -8,7 +10,7 @@ describe "adapter is set" do
8
10
  QueueBus.send(:reset)
9
11
  end
10
12
 
11
- it "should be defaulting to Data from spec_helper" do
13
+ it 'should be defaulting to Data from spec_helper' do
12
14
  expect(QueueBus.adapter.is_a?(adapter_under_test_class)).to eq(true)
13
15
  end
14
16
  end
@@ -1,151 +1,193 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module QueueBus
4
6
  describe Application do
5
- describe ".all" do
6
- it "should return empty array when none" do
7
+ describe '.all' do
8
+ it 'should return empty array when none' do
7
9
  expect(Application.all).to eq([])
8
10
  end
9
- it "should return registered applications when there are some" do
10
- Application.new("One").subscribe(test_list(test_sub("fdksjh")))
11
- Application.new("Two").subscribe(test_list(test_sub("fdklhf")))
12
- Application.new("Three").subscribe(test_list(test_sub("fkld")))
11
+ it 'should return registered applications when there are some' do
12
+ Application.new('One').subscribe(test_list(test_sub('fdksjh')))
13
+ Application.new('Two').subscribe(test_list(test_sub('fdklhf')))
14
+ Application.new('Three').subscribe(test_list(test_sub('fkld')))
13
15
 
14
- expect(Application.all.collect(&:app_key)).to match_array(["one", "two", "three"])
16
+ expect(Application.all.collect(&:app_key)).to match_array(%w[one two three])
15
17
 
16
- Application.new("two").unsubscribe
17
- expect(Application.all.collect(&:app_key)).to match_array(["one", "three"])
18
+ Application.new('two').unsubscribe
19
+ expect(Application.all.collect(&:app_key)).to match_array(%w[one three])
18
20
  end
19
21
  end
20
22
 
21
- describe ".new" do
22
- it "should have a key" do
23
- expect(Application.new("something").app_key).to eq("something")
23
+ describe '.new' do
24
+ it 'should have a key' do
25
+ expect(Application.new('something').app_key).to eq('something')
24
26
 
25
- expect(Application.new("some thing").app_key).to eq("some_thing")
26
- expect(Application.new("some-thing").app_key).to eq("some_thing")
27
- expect(Application.new("some_thing").app_key).to eq("some_thing")
28
- expect(Application.new("Some Thing").app_key).to eq("some_thing")
27
+ expect(Application.new('some thing').app_key).to eq('some_thing')
28
+ expect(Application.new('some-thing').app_key).to eq('some_thing')
29
+ expect(Application.new('some_thing').app_key).to eq('some_thing')
30
+ expect(Application.new('Some Thing').app_key).to eq('some_thing')
29
31
  end
30
32
 
31
- it "should raise an error if not valid" do
32
- expect {
33
- Application.new("")
34
- }.to raise_error(RuntimeError, "Invalid application name")
33
+ it 'should raise an error if not valid' do
34
+ expect do
35
+ Application.new('')
36
+ end.to raise_error(RuntimeError, 'Invalid application name')
35
37
 
36
- expect {
38
+ expect do
37
39
  Application.new(nil)
38
- }.to raise_error(RuntimeError, "Invalid application name")
40
+ end.to raise_error(RuntimeError, 'Invalid application name')
39
41
 
40
- expect {
41
- Application.new("/")
42
- }.to raise_error(RuntimeError, "Invalid application name")
42
+ expect do
43
+ Application.new('/')
44
+ end.to raise_error(RuntimeError, 'Invalid application name')
43
45
  end
44
46
  end
45
47
 
46
- describe "#read_redis_hash" do
47
- it "should handle old and new values" do
48
-
49
- QueueBus.redis { |redis| redis.hset("bus_app:myapp", "new_one", QueueBus::Util.encode("queue_name" => "x", "bus_event_type" => "event_name") ) }
50
- QueueBus.redis { |redis| redis.hset("bus_app:myapp", "old_one", "oldqueue_name") }
51
- app = Application.new("myapp")
48
+ describe '#read_redis_hash' do
49
+ it 'should handle old and new values' do
50
+ QueueBus.redis { |redis| redis.hset('bus_app:myapp', 'new_one', QueueBus::Util.encode('queue_name' => 'x', 'bus_event_type' => 'event_name')) }
51
+ QueueBus.redis { |redis| redis.hset('bus_app:myapp', 'old_one', 'oldqueue_name') }
52
+ app = Application.new('myapp')
52
53
  val = app.send(:read_redis_hash)
53
- expect(val).to eq({"new_one" => {"queue_name" => "x", "bus_event_type" => "event_name"}, "old_one" => "oldqueue_name"})
54
+ expect(val).to eq('new_one' => { 'queue_name' => 'x', 'bus_event_type' => 'event_name' }, 'old_one' => 'oldqueue_name')
54
55
  end
55
56
  end
56
57
 
57
- describe "#subscribe" do
58
- let(:sub1) { test_sub("event_one", "default") }
59
- let(:sub2) { test_sub("event_two", "default") }
60
- let(:sub3) { test_sub("event_three", "other") }
61
- it "should add array to redis" do
62
- expect(QueueBus.redis { |redis| redis.get("bus_app:myapp") }).to be_nil
63
- Application.new("myapp").subscribe(test_list(sub1, sub2))
64
-
65
- expect(QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }).to eq({"event_two"=>"{\"queue_name\":\"default\",\"key\":\"event_two\",\"class\":\"::QueueBus::Rider\",\"matcher\":{\"bus_event_type\":\"event_two\"}}",
66
- "event_one"=>"{\"queue_name\":\"default\",\"key\":\"event_one\",\"class\":\"::QueueBus::Rider\",\"matcher\":{\"bus_event_type\":\"event_one\"}}"})
67
- expect(QueueBus.redis { |redis| redis.hkeys("bus_app:myapp") }).to match_array(["event_one", "event_two"])
68
- expect(QueueBus.redis { |redis| redis.smembers("bus_apps") }).to match_array(["myapp"])
58
+ describe '#subscribe' do
59
+ let(:sub1) { test_sub('event_one', 'default') }
60
+ let(:sub2) { test_sub('event_two', 'default') }
61
+ let(:sub3) { test_sub('event_three', 'other') }
62
+ it 'should add array to redis' do
63
+ expect(QueueBus.redis { |redis| redis.get('bus_app:myapp') }).to be_nil
64
+ Application.new('myapp').subscribe(test_list(sub1, sub2))
65
+
66
+ expect(QueueBus.redis { |redis| redis.hgetall('bus_app:myapp') }).to eq('event_two' => '{"queue_name":"default","key":"event_two","class":"::QueueBus::Rider","matcher":{"bus_event_type":"event_two"}}',
67
+ 'event_one' => '{"queue_name":"default","key":"event_one","class":"::QueueBus::Rider","matcher":{"bus_event_type":"event_one"}}')
68
+ expect(QueueBus.redis { |redis| redis.hkeys('bus_app:myapp') }).to match_array(%w[event_one event_two])
69
+ expect(QueueBus.redis { |redis| redis.smembers('bus_apps') }).to match_array(['myapp'])
69
70
  end
70
- it "should add string to redis" do
71
- expect(QueueBus.redis { |redis| redis.get("bus_app:myapp") }).to be_nil
72
- Application.new("myapp").subscribe(test_list(sub1))
71
+ it 'should add string to redis' do
72
+ expect(QueueBus.redis { |redis| redis.get('bus_app:myapp') }).to be_nil
73
+ Application.new('myapp').subscribe(test_list(sub1))
73
74
 
74
- expect(QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }).to eq({"event_one"=>"{\"queue_name\":\"default\",\"key\":\"event_one\",\"class\":\"::QueueBus::Rider\",\"matcher\":{\"bus_event_type\":\"event_one\"}}"})
75
- expect(QueueBus.redis { |redis| redis.hkeys("bus_app:myapp") }).to match_array(["event_one"])
76
- expect(QueueBus.redis { |redis| redis.smembers("bus_apps") }).to match_array(["myapp"])
75
+ expect(QueueBus.redis { |redis| redis.hgetall('bus_app:myapp') }).to eq('event_one' => '{"queue_name":"default","key":"event_one","class":"::QueueBus::Rider","matcher":{"bus_event_type":"event_one"}}')
76
+ expect(QueueBus.redis { |redis| redis.hkeys('bus_app:myapp') }).to match_array(['event_one'])
77
+ expect(QueueBus.redis { |redis| redis.smembers('bus_apps') }).to match_array(['myapp'])
77
78
  end
78
- it "should multiple queues to redis" do
79
- expect(QueueBus.redis { |redis| redis.get("bus_app:myapp") }).to be_nil
80
- Application.new("myapp").subscribe(test_list(sub1, sub2, sub3))
81
- expect(QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }).to eq({"event_two"=>"{\"queue_name\":\"default\",\"key\":\"event_two\",\"class\":\"::QueueBus::Rider\",\"matcher\":{\"bus_event_type\":\"event_two\"}}", "event_one"=>"{\"queue_name\":\"default\",\"key\":\"event_one\",\"class\":\"::QueueBus::Rider\",\"matcher\":{\"bus_event_type\":\"event_one\"}}",
82
- "event_three"=>"{\"queue_name\":\"other\",\"key\":\"event_three\",\"class\":\"::QueueBus::Rider\",\"matcher\":{\"bus_event_type\":\"event_three\"}}"})
83
- expect(QueueBus.redis { |redis| redis.hkeys("bus_app:myapp") }).to match_array(["event_three", "event_two", "event_one"])
84
- expect(QueueBus.redis { |redis| redis.smembers("bus_apps") }).to match_array(["myapp"])
79
+ it 'should multiple queues to redis' do
80
+ expect(QueueBus.redis { |redis| redis.get('bus_app:myapp') }).to be_nil
81
+ Application.new('myapp').subscribe(test_list(sub1, sub2, sub3))
82
+ expect(QueueBus.redis { |redis| redis.hgetall('bus_app:myapp') }).to eq('event_two' => '{"queue_name":"default","key":"event_two","class":"::QueueBus::Rider","matcher":{"bus_event_type":"event_two"}}', 'event_one' => '{"queue_name":"default","key":"event_one","class":"::QueueBus::Rider","matcher":{"bus_event_type":"event_one"}}',
83
+ 'event_three' => '{"queue_name":"other","key":"event_three","class":"::QueueBus::Rider","matcher":{"bus_event_type":"event_three"}}')
84
+ expect(QueueBus.redis { |redis| redis.hkeys('bus_app:myapp') }).to match_array(%w[event_three event_two event_one])
85
+ expect(QueueBus.redis { |redis| redis.smembers('bus_apps') }).to match_array(['myapp'])
85
86
  end
86
87
 
87
- it "should do nothing if nil or empty" do
88
+ it 'should do nothing if nil or empty' do
89
+ expect(QueueBus.redis { |redis| redis.get('bus_app:myapp') }).to be_nil
88
90
 
89
- expect(QueueBus.redis { |redis| redis.get("bus_app:myapp") }).to be_nil
91
+ Application.new('myapp').subscribe(nil)
92
+ expect(QueueBus.redis { |redis| redis.get('bus_app:myapp') }).to be_nil
90
93
 
91
- Application.new("myapp").subscribe(nil)
92
- expect(QueueBus.redis { |redis| redis.get("bus_app:myapp") }).to be_nil
93
-
94
- Application.new("myapp").subscribe([])
95
- expect(QueueBus.redis { |redis| redis.get("bus_app:myapp") }).to be_nil
94
+ Application.new('myapp').subscribe([])
95
+ expect(QueueBus.redis { |redis| redis.get('bus_app:myapp') }).to be_nil
96
96
  end
97
97
 
98
- it "should call unsubscribe" do
99
- app = Application.new("myapp")
98
+ it 'should call unsubscribe' do
99
+ app = Application.new('myapp')
100
100
  expect(app).to receive(:unsubscribe)
101
101
  app.subscribe([])
102
102
  end
103
103
  end
104
104
 
105
105
  describe "#unsubscribe" do
106
- it "should remove items" do
107
- QueueBus.redis { |redis| redis.sadd("bus_apps", "myapp") }
108
- QueueBus.redis { |redis| redis.sadd("bus_apps", "other") }
109
- QueueBus.redis { |redis| redis.hset("bus_app:myapp", "event_one", "myapp_default") }
106
+ context "when a queue is not specified" do
107
+ it "removes all subscriptions" do
108
+ myapp_list = SubscriptionList.new
109
+ other_list = SubscriptionList.new
110
+
111
+ subscription_1 = Subscription.new("myapp_default", "key1", "MyClass1", {"bus_event_type" => "event_one"})
112
+ subscription_2 = Subscription.new("myapp_default", "key2", "MyClass2", {"bus_event_type" => "event_two"})
113
+ subscription_3 = Subscription.new("myapp_other_queue", "key1", "MyClass1", {"bus_event_type" => "event_one"})
114
+
115
+ myapp_list.add(subscription_1)
116
+ myapp_list.add(subscription_2)
117
+ other_list.add(subscription_3)
118
+
119
+ Application.new("myapp").subscribe(myapp_list)
120
+ Application.new("other").subscribe(other_list)
121
+
122
+ expect(QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }).to eq({
123
+ "key1" => "{\"queue_name\":\"myapp_default\",\"key\":\"key1\",\"class\":\"MyClass1\",\"matcher\":{\"bus_event_type\":\"event_one\"}}",
124
+ "key2" => "{\"queue_name\":\"myapp_default\",\"key\":\"key2\",\"class\":\"MyClass2\",\"matcher\":{\"bus_event_type\":\"event_two\"}}"
125
+ })
126
+
127
+ Application.new("myapp").unsubscribe
128
+
129
+ expect(QueueBus.redis { |redis| redis.smembers("bus_apps") }).to eq(["other"])
130
+ expect(QueueBus.redis { |redis| redis.hlen("bus_app:myapp") }).to eq(0)
131
+ expect(QueueBus.redis { |redis| redis.hlen("bus_app:other") }).to eq(1)
132
+ end
133
+ end
134
+
135
+ context "when a queue is specified" do
136
+ it "removes only that key" do
137
+ list = SubscriptionList.new
138
+
139
+ subscription_1 = Subscription.new("myapp_default", "key1", "MyClass1", {"bus_event_type" => "event_one"})
140
+ subscription_2 = Subscription.new("myapp_other_queue", "key2", "MyClass2", {"bus_event_type" => "event_two"})
141
+
142
+ list.add(subscription_1)
143
+ list.add(subscription_2)
144
+
145
+ Application.new("myapp").subscribe(list)
146
+
147
+ expect(QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }).to eq({
148
+ "key1" => "{\"queue_name\":\"myapp_default\",\"key\":\"key1\",\"class\":\"MyClass1\",\"matcher\":{\"bus_event_type\":\"event_one\"}}",
149
+ "key2" => "{\"queue_name\":\"myapp_other_queue\",\"key\":\"key2\",\"class\":\"MyClass2\",\"matcher\":{\"bus_event_type\":\"event_two\"}}"
150
+ })
110
151
 
111
- Application.new("myapp").unsubscribe
152
+ Application.new("myapp").unsubscribe_queue("myapp_default")
112
153
 
113
- expect(QueueBus.redis { |redis| redis.smembers("bus_apps") }).to eq(["other"])
114
- expect(QueueBus.redis { |redis| redis.get("bus_app:myapp") }).to be_nil
154
+ expect(QueueBus.redis { |redis| redis.smembers("bus_apps") }).to eq(["myapp"])
155
+ expect(QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }).to eq({"key2" => "{\"queue_name\":\"myapp_other_queue\",\"key\":\"key2\",\"class\":\"MyClass2\",\"matcher\":{\"bus_event_type\":\"event_two\"}}"})
156
+ end
115
157
  end
116
158
  end
117
159
 
118
- describe "#subscription_matches" do
119
- it "should return if it is there" do
120
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"three").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to eq([])
160
+ describe '#subscription_matches' do
161
+ it 'should return if it is there' do
162
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'three').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to eq([])
121
163
 
122
- subs = test_list(test_sub("one_x"), test_sub("one_y"), test_sub("one"), test_sub("two"))
123
- Application.new("myapp").subscribe(subs)
124
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"three").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to eq([])
164
+ subs = test_list(test_sub('one_x'), test_sub('one_y'), test_sub('one'), test_sub('two'))
165
+ Application.new('myapp').subscribe(subs)
166
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'three').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to eq([])
125
167
 
126
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"two").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "two", "default", "::QueueBus::Rider"]])
127
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"one").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "one", "default", "::QueueBus::Rider"]])
168
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'two').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', 'two', 'default', '::QueueBus::Rider']])
169
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'one').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', 'one', 'default', '::QueueBus::Rider']])
128
170
  end
129
171
 
130
- it "should handle * wildcards" do
131
- subs = test_list(test_sub("one.+"), test_sub("one"), test_sub("one_.*"), test_sub("two"))
132
- Application.new("myapp").subscribe(subs)
133
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"three").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to eq([])
172
+ it 'should handle * wildcards' do
173
+ subs = test_list(test_sub('one.+'), test_sub('one'), test_sub('one_.*'), test_sub('two'))
174
+ Application.new('myapp').subscribe(subs)
175
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'three').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to eq([])
134
176
 
135
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"onex").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "one.+", "default", "::QueueBus::Rider"]])
136
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"one").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "one", "default", "::QueueBus::Rider"]])
137
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"one_x").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "one.+","default", "::QueueBus::Rider"], ["myapp", "one_.*", "default", "::QueueBus::Rider"]])
177
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'onex').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', 'one.+', 'default', '::QueueBus::Rider']])
178
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'one').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', 'one', 'default', '::QueueBus::Rider']])
179
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'one_x').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', 'one.+', 'default', '::QueueBus::Rider'], ['myapp', 'one_.*', 'default', '::QueueBus::Rider']])
138
180
  end
139
181
 
140
- it "should handle actual regular expressions" do
141
- subs = test_list(test_sub(/one.+/), test_sub("one"), test_sub(/one_.*/), test_sub("two"))
142
- Application.new("myapp").subscribe(subs)
143
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"three").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to eq([])
182
+ it 'should handle actual regular expressions' do
183
+ subs = test_list(test_sub(/one.+/), test_sub('one'), test_sub(/one_.*/), test_sub('two'))
184
+ Application.new('myapp').subscribe(subs)
185
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'three').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to eq([])
144
186
 
145
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"onex").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "(?-mix:one.+)", "default", "::QueueBus::Rider"]])
146
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"donex").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "(?-mix:one.+)", "default", "::QueueBus::Rider"]])
147
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"one").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "one" ,"default", "::QueueBus::Rider"]])
148
- expect(Application.new("myapp").subscription_matches("bus_event_type"=>"one_x").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}).to match_array([["myapp", "(?-mix:one.+)", "default", "::QueueBus::Rider"], ["myapp", "(?-mix:one_.*)", "default", "::QueueBus::Rider"]])
187
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'onex').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', '(?-mix:one.+)', 'default', '::QueueBus::Rider']])
188
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'donex').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', '(?-mix:one.+)', 'default', '::QueueBus::Rider']])
189
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'one').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', 'one', 'default', '::QueueBus::Rider']])
190
+ expect(Application.new('myapp').subscription_matches('bus_event_type' => 'one_x').collect { |s| [s.app_key, s.key, s.queue_name, s.class_name] }).to match_array([['myapp', '(?-mix:one.+)', 'default', '::QueueBus::Rider'], ['myapp', '(?-mix:one_.*)', 'default', '::QueueBus::Rider']])
149
191
  end
150
192
  end
151
193
  end