sidekiq-bus 0.5.2
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 +7 -0
- data/.gitignore +5 -0
- data/.rbenv-version +1 -0
- data/.rspec +1 -0
- data/Gemfile +5 -0
- data/MIT-LICENSE +20 -0
- data/README.mdown +264 -0
- data/Rakefile +2 -0
- data/lib/sidekiq-bus.rb +9 -0
- data/lib/sidekiq_bus/adapter.rb +28 -0
- data/lib/sidekiq_bus/tasks.rb +93 -0
- data/lib/sidekiq_bus/version.rb +3 -0
- data/sidekiq-bus.gemspec +27 -0
- data/spec/adapter/support.rb +14 -0
- data/spec/adapter_spec.rb +14 -0
- data/spec/application_spec.rb +152 -0
- data/spec/config_spec.rb +83 -0
- data/spec/dispatch_spec.rb +76 -0
- data/spec/driver_spec.rb +109 -0
- data/spec/heartbeat_spec.rb +44 -0
- data/spec/integration_spec.rb +53 -0
- data/spec/matcher_spec.rb +143 -0
- data/spec/publish_spec.rb +98 -0
- data/spec/publisher_spec.rb +7 -0
- data/spec/rider_spec.rb +39 -0
- data/spec/spec_helper.rb +69 -0
- data/spec/subscriber_spec.rb +270 -0
- data/spec/subscription_list_spec.rb +43 -0
- data/spec/subscription_spec.rb +53 -0
- data/spec/worker_spec.rb +32 -0
- metadata +167 -0
data/sidekiq-bus.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "sidekiq_bus/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "sidekiq-bus"
|
7
|
+
s.version = SidekiqBus::VERSION
|
8
|
+
s.authors = ["Brian Leonard"]
|
9
|
+
s.email = ["brian@bleonard.com"]
|
10
|
+
s.homepage = "https://github.com/queue-bus/sidekiq-bus"
|
11
|
+
s.summary = %q{A simple event bus on top of Resque}
|
12
|
+
s.description = %q{A simple event bus on top of Resque. Publish and subscribe to events as they occur through a queue.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "sidekiq-bus"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
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"]
|
20
|
+
|
21
|
+
s.add_dependency('queue-bus', '0.5.2')
|
22
|
+
s.add_dependency('sidekiq', ['>= 3.0.0', '< 4.0'])
|
23
|
+
|
24
|
+
s.add_development_dependency("rspec")
|
25
|
+
s.add_development_dependency("timecop")
|
26
|
+
s.add_development_dependency("json_pure")
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'sidekiq-bus'
|
2
|
+
|
3
|
+
def reset_test_adapter
|
4
|
+
QueueBus.send(:reset)
|
5
|
+
QueueBus.adapter = QueueBus::Adapters::Sidekiq.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def adapter_under_test_class
|
9
|
+
QueueBus::Adapters::Sidekiq
|
10
|
+
end
|
11
|
+
|
12
|
+
def adapter_under_test_symbol
|
13
|
+
:sidekiq
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "adapter is set" do
|
4
|
+
it "should call it's enabled! method on init" do
|
5
|
+
QueueBus.send(:reset)
|
6
|
+
adapter_under_test_class.any_instance.should_receive(:enabled!)
|
7
|
+
instance = adapter_under_test_class.new
|
8
|
+
QueueBus.send(:reset)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be defaulting to Data from spec_helper" do
|
12
|
+
QueueBus.adapter.is_a?(adapter_under_test_class).should == true
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module QueueBus
|
4
|
+
describe Application do
|
5
|
+
describe ".all" do
|
6
|
+
it "should return empty array when none" do
|
7
|
+
Application.all.should == []
|
8
|
+
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")))
|
13
|
+
|
14
|
+
Application.all.collect(&:app_key).should =~ ["one", "two", "three"]
|
15
|
+
|
16
|
+
Application.new("two").unsubscribe
|
17
|
+
Application.all.collect(&:app_key).should =~ ["one", "three"]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".new" do
|
22
|
+
it "should have a key" do
|
23
|
+
Application.new("something").app_key.should == "something"
|
24
|
+
|
25
|
+
Application.new("some thing").app_key.should == "some_thing"
|
26
|
+
Application.new("some-thing").app_key.should == "some_thing"
|
27
|
+
Application.new("some_thing").app_key.should == "some_thing"
|
28
|
+
Application.new("Some Thing").app_key.should == "some_thing"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should raise an error if not valid" do
|
32
|
+
lambda {
|
33
|
+
Application.new("")
|
34
|
+
}.should raise_error
|
35
|
+
|
36
|
+
lambda {
|
37
|
+
Application.new(nil)
|
38
|
+
}.should raise_error
|
39
|
+
|
40
|
+
lambda {
|
41
|
+
Application.new("/")
|
42
|
+
}.should raise_error
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
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")
|
52
|
+
val = app.send(:read_redis_hash)
|
53
|
+
val.should == {"new_one" => {"queue_name" => "x", "bus_event_type" => "event_name"}, "old_one" => "oldqueue_name"}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
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
|
+
QueueBus.redis { |redis| redis.get("bus_app:myapp") }.should be_nil
|
63
|
+
Application.new("myapp").subscribe(test_list(sub1, sub2))
|
64
|
+
|
65
|
+
QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }.should == {"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
|
+
QueueBus.redis { |redis| redis.hkeys("bus_app:myapp") }.should =~ ["event_one", "event_two"]
|
68
|
+
QueueBus.redis { |redis| redis.smembers("bus_apps") }.should =~ ["myapp"]
|
69
|
+
end
|
70
|
+
it "should add string to redis" do
|
71
|
+
QueueBus.redis { |redis| redis.get("bus_app:myapp") }.should be_nil
|
72
|
+
Application.new("myapp").subscribe(test_list(sub1))
|
73
|
+
|
74
|
+
QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }.should == {"event_one"=>"{\"queue_name\":\"default\",\"key\":\"event_one\",\"class\":\"::QueueBus::Rider\",\"matcher\":{\"bus_event_type\":\"event_one\"}}"}
|
75
|
+
QueueBus.redis { |redis| redis.hkeys("bus_app:myapp") }.should =~ ["event_one"]
|
76
|
+
QueueBus.redis { |redis| redis.smembers("bus_apps") }.should =~ ["myapp"]
|
77
|
+
end
|
78
|
+
it "should multiple queues to redis" do
|
79
|
+
QueueBus.redis { |redis| redis.get("bus_app:myapp") }.should be_nil
|
80
|
+
Application.new("myapp").subscribe(test_list(sub1, sub2, sub3))
|
81
|
+
QueueBus.redis { |redis| redis.hgetall("bus_app:myapp") }.should == {"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
|
+
QueueBus.redis { |redis| redis.hkeys("bus_app:myapp") }.should =~ ["event_three", "event_two", "event_one"]
|
84
|
+
QueueBus.redis { |redis| redis.smembers("bus_apps") }.should =~ ["myapp"]
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should do nothing if nil or empty" do
|
88
|
+
|
89
|
+
QueueBus.redis { |redis| redis.get("bus_app:myapp") }.should be_nil
|
90
|
+
|
91
|
+
Application.new("myapp").subscribe(nil)
|
92
|
+
QueueBus.redis { |redis| redis.get("bus_app:myapp") }.should be_nil
|
93
|
+
|
94
|
+
Application.new("myapp").subscribe([])
|
95
|
+
QueueBus.redis { |redis| redis.get("bus_app:myapp") }.should be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should call unsubscribe" do
|
99
|
+
app = Application.new("myapp")
|
100
|
+
app.should_receive(:unsubscribe)
|
101
|
+
app.subscribe([])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
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") }
|
110
|
+
|
111
|
+
Application.new("myapp").unsubscribe
|
112
|
+
|
113
|
+
QueueBus.redis { |redis| redis.smembers("bus_apps") }.should == ["other"]
|
114
|
+
QueueBus.redis { |redis| redis.get("bus_app:myapp") }.should be_nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#subscription_matches" do
|
119
|
+
it "should return if it is there" do
|
120
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"three").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should == []
|
121
|
+
|
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
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"three").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should == []
|
125
|
+
|
126
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"two").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "two", "default", "::QueueBus::Rider"]]
|
127
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"one").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "one", "default", "::QueueBus::Rider"]]
|
128
|
+
end
|
129
|
+
|
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
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"three").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should == []
|
134
|
+
|
135
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"onex").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "one.+", "default", "::QueueBus::Rider"]]
|
136
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"one").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "one", "default", "::QueueBus::Rider"]]
|
137
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"one_x").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "one.+","default", "::QueueBus::Rider"], ["myapp", "one_.*", "default", "::QueueBus::Rider"]]
|
138
|
+
end
|
139
|
+
|
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
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"three").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should == []
|
144
|
+
|
145
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"onex").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "(?-mix:one.+)", "default", "::QueueBus::Rider"]]
|
146
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"donex").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "(?-mix:one.+)", "default", "::QueueBus::Rider"]]
|
147
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"one").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "one" ,"default", "::QueueBus::Rider"]]
|
148
|
+
Application.new("myapp").subscription_matches("bus_event_type"=>"one_x").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["myapp", "(?-mix:one.+)", "default", "::QueueBus::Rider"], ["myapp", "(?-mix:one_.*)", "default", "::QueueBus::Rider"]]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module QueueBus
|
4
|
+
module Adapters
|
5
|
+
class TestOne
|
6
|
+
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "QueueBus config" do
|
12
|
+
it "should set the default app key" do
|
13
|
+
QueueBus.default_app_key.should == nil
|
14
|
+
|
15
|
+
QueueBus.default_app_key = "my_app"
|
16
|
+
QueueBus.default_app_key.should == "my_app"
|
17
|
+
|
18
|
+
QueueBus.default_app_key = "something here"
|
19
|
+
QueueBus.default_app_key.should == "something_here"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should set the default queue" do
|
23
|
+
QueueBus.default_queue.should == nil
|
24
|
+
|
25
|
+
QueueBus.default_queue = "my_queue"
|
26
|
+
QueueBus.default_queue.should == "my_queue"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should set the local mode" do
|
30
|
+
QueueBus.local_mode.should == nil
|
31
|
+
QueueBus.local_mode = :standalone
|
32
|
+
QueueBus.local_mode.should == :standalone
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should set the hostname" do
|
36
|
+
QueueBus.hostname.should_not == nil
|
37
|
+
QueueBus.hostname = "whatever"
|
38
|
+
QueueBus.hostname.should == "whatever"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should set before_publish callback" do
|
42
|
+
QueueBus.before_publish = lambda {|attributes| 42 }
|
43
|
+
QueueBus.before_publish_callback({}).should == 42
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
it "should use the default Redis connection" do
|
48
|
+
QueueBus.redis { |redis| redis }.should_not eq(nil)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should default to given adapter" do
|
52
|
+
QueueBus.adapter.is_a?(adapter_under_test_class).should == true
|
53
|
+
|
54
|
+
# and should raise if already set
|
55
|
+
lambda {
|
56
|
+
QueueBus.adapter = :data
|
57
|
+
}.should raise_error
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with a fresh load" do
|
61
|
+
before(:each) do
|
62
|
+
QueueBus.send(:reset)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should be able to be set to resque" do
|
66
|
+
QueueBus.adapter = adapter_under_test_symbol
|
67
|
+
QueueBus.adapter.is_a?(adapter_under_test_class).should == true
|
68
|
+
|
69
|
+
# and should raise if already set
|
70
|
+
lambda {
|
71
|
+
QueueBus.adapter = :data
|
72
|
+
}.should raise_error
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be able to be set to something else" do
|
76
|
+
|
77
|
+
QueueBus.adapter = :test_one
|
78
|
+
QueueBus.adapter.is_a?(QueueBus::Adapters::TestOne).should == true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module QueueBus
|
4
|
+
describe Dispatch do
|
5
|
+
it "should not start with any applications" do
|
6
|
+
Dispatch.new("d").subscriptions.size.should == 0
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should register code to run and execute it" do
|
10
|
+
dispatch = Dispatch.new("d")
|
11
|
+
dispatch.subscribe("my_event") do |attrs|
|
12
|
+
Runner1.run(attrs)
|
13
|
+
end
|
14
|
+
sub = dispatch.subscriptions.key("my_event")
|
15
|
+
sub.send(:executor).is_a?(Proc).should == true
|
16
|
+
|
17
|
+
Runner.value.should == 0
|
18
|
+
dispatch.execute("my_event", {"bus_event_type" => "my_event", "ok" => true})
|
19
|
+
Runner1.value.should == 1
|
20
|
+
Runner1.attributes.should == {"bus_event_type" => "my_event", "ok" => true}
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not crash if not there" do
|
25
|
+
lambda {
|
26
|
+
Dispatch.new("d").execute("fdkjh", "bus_event_type" => "fdkjh")
|
27
|
+
}.should_not raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "Top Level" do
|
31
|
+
before(:each) do
|
32
|
+
QueueBus.dispatch("testit") do
|
33
|
+
subscribe "event1" do |attributes|
|
34
|
+
Runner2.run(attributes)
|
35
|
+
end
|
36
|
+
|
37
|
+
subscribe "event2" do
|
38
|
+
Runner2.run({})
|
39
|
+
end
|
40
|
+
|
41
|
+
high "event3" do
|
42
|
+
Runner2.run({})
|
43
|
+
end
|
44
|
+
|
45
|
+
low /^patt.+ern/ do
|
46
|
+
Runner.run({})
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should register and run" do
|
52
|
+
Runner2.value.should == 0
|
53
|
+
QueueBus.dispatcher_execute("testit", "event2", "bus_event_type" => "event2")
|
54
|
+
Runner2.value.should == 1
|
55
|
+
QueueBus.dispatcher_execute("testit", "event1", "bus_event_type" => "event1")
|
56
|
+
Runner2.value.should == 2
|
57
|
+
QueueBus.dispatcher_execute("testit", "event1", "bus_event_type" => "event1")
|
58
|
+
Runner2.value.should == 3
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return the subscriptions" do
|
62
|
+
dispatcher = QueueBus.dispatcher_by_key("testit")
|
63
|
+
subs = dispatcher.subscriptions.all
|
64
|
+
tuples = subs.collect{ |sub| [sub.key, sub.queue_name]}
|
65
|
+
tuples.should =~ [ ["event1", "testit_default"],
|
66
|
+
["event2", "testit_default"],
|
67
|
+
["event3", "testit_high"],
|
68
|
+
[ "(?-mix:^patt.+ern)", "testit_low"]
|
69
|
+
]
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
data/spec/driver_spec.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module QueueBus
|
4
|
+
describe Driver do
|
5
|
+
before(:each) do
|
6
|
+
Application.new("app1").subscribe(test_list(test_sub("event1"), test_sub("event2"), test_sub("event3")))
|
7
|
+
Application.new("app2").subscribe(test_list(test_sub("event2","other"), test_sub("event4", "more")))
|
8
|
+
Application.new("app3").subscribe(test_list(test_sub("event[45]"), test_sub("event5"), test_sub("event6")))
|
9
|
+
Timecop.freeze
|
10
|
+
end
|
11
|
+
after(:each) do
|
12
|
+
Timecop.return
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:bus_attrs) { {"bus_driven_at" => Time.now.to_i, "bus_rider_class_name"=>"::QueueBus::Rider", "bus_class_proxy" => "::QueueBus::Rider"} }
|
16
|
+
|
17
|
+
describe ".subscription_matches" do
|
18
|
+
it "return empty array when none" do
|
19
|
+
Driver.subscription_matches("bus_event_type" => "else").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should == []
|
20
|
+
Driver.subscription_matches("bus_event_type" => "event").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should == []
|
21
|
+
end
|
22
|
+
it "should return a match" do
|
23
|
+
Driver.subscription_matches("bus_event_type" => "event1").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app1", "event1", "default", "::QueueBus::Rider"]]
|
24
|
+
Driver.subscription_matches("bus_event_type" => "event6").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app3", "event6", "default", "::QueueBus::Rider"]]
|
25
|
+
end
|
26
|
+
it "should match multiple apps" do
|
27
|
+
Driver.subscription_matches("bus_event_type" => "event2").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app1", "event2", "default", "::QueueBus::Rider"], ["app2", "event2", "other", "::QueueBus::Rider"]]
|
28
|
+
end
|
29
|
+
it "should match multiple apps with patterns" do
|
30
|
+
Driver.subscription_matches("bus_event_type" => "event4").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app3", "event[45]", "default", "::QueueBus::Rider"], ["app2", "event4", "more", "::QueueBus::Rider"]]
|
31
|
+
end
|
32
|
+
it "should match multiple events in same app" do
|
33
|
+
Driver.subscription_matches("bus_event_type" => "event5").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app3", "event[45]", "default", "::QueueBus::Rider"], ["app3", "event5", "default", "::QueueBus::Rider"]]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe ".perform" do
|
38
|
+
let(:attributes) { {"x" => "y", "bus_class_proxy" => "ResqueBus::Driver"} }
|
39
|
+
|
40
|
+
before(:each) do
|
41
|
+
QueueBus.redis { |redis| redis.smembers("queues") }.should == []
|
42
|
+
QueueBus.redis { |redis| redis.lpop("queue:app1_default") }.should be_nil
|
43
|
+
QueueBus.redis { |redis| redis.lpop("queue:app2_default") }.should be_nil
|
44
|
+
QueueBus.redis { |redis| redis.lpop("queue:app3_default") }.should be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should do nothing when empty" do
|
48
|
+
Driver.perform(attributes.merge("bus_event_type" => "else"))
|
49
|
+
QueueBus.redis { |redis| redis.smembers("queues") }.should == []
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should queue up the riders in redis" do
|
53
|
+
QueueBus.redis { |redis| redis.lpop("queue:app1_default") }.should be_nil
|
54
|
+
Driver.perform(attributes.merge("bus_event_type" => "event1"))
|
55
|
+
QueueBus.redis { |redis| redis.smembers("queues") }.should =~ ["default"]
|
56
|
+
|
57
|
+
hash = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:default") })
|
58
|
+
hash["class"].should == "QueueBus::Worker"
|
59
|
+
hash["args"].size.should == 1
|
60
|
+
JSON.parse(hash["args"].first).should == {"bus_rider_app_key"=>"app1", "x" => "y", "bus_event_type" => "event1", "bus_rider_sub_key"=>"event1", "bus_rider_queue" => "default"}.merge(bus_attrs)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should queue up to multiple" do
|
64
|
+
Driver.perform(attributes.merge("bus_event_type" => "event4"))
|
65
|
+
QueueBus.redis { |redis| redis.smembers("queues") }.should =~ ["default", "more"]
|
66
|
+
|
67
|
+
hash = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:more") })
|
68
|
+
hash["class"].should == "QueueBus::Worker"
|
69
|
+
hash["args"].size.should == 1
|
70
|
+
JSON.parse(hash["args"].first).should == {"bus_rider_app_key"=>"app2", "x" => "y", "bus_event_type" => "event4", "bus_rider_sub_key"=>"event4", "bus_rider_queue" => "more"}.merge(bus_attrs)
|
71
|
+
|
72
|
+
hash = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:default") })
|
73
|
+
hash["class"].should == "QueueBus::Worker"
|
74
|
+
hash["args"].size.should == 1
|
75
|
+
JSON.parse(hash["args"].first).should == {"bus_rider_app_key"=>"app3", "x" => "y", "bus_event_type" => "event4", "bus_rider_sub_key"=>"event[45]", "bus_rider_queue" => "default"}.merge(bus_attrs)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should queue up to the same" do
|
79
|
+
Driver.perform(attributes.merge("bus_event_type" => "event5"))
|
80
|
+
QueueBus.redis { |redis| redis.smembers("queues") }.should =~ ["default"]
|
81
|
+
|
82
|
+
QueueBus.redis { |redis| redis.llen("queue:default") }.should == 2
|
83
|
+
|
84
|
+
pop1 = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:default") })
|
85
|
+
pop2 = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:default") })
|
86
|
+
|
87
|
+
pargs1 = JSON.parse(pop1["args"].first)
|
88
|
+
pargs2 = JSON.parse(pop2["args"].first)
|
89
|
+
if pargs1["bus_rider_sub_key"] == "event5"
|
90
|
+
hash1 = pop1
|
91
|
+
hash2 = pop2
|
92
|
+
args1 = pargs1
|
93
|
+
args2 = pargs2
|
94
|
+
else
|
95
|
+
hash1 = pop2
|
96
|
+
hash2 = pop1
|
97
|
+
args1 = pargs2
|
98
|
+
args2 = pargs1
|
99
|
+
end
|
100
|
+
|
101
|
+
hash1["class"].should == "QueueBus::Worker"
|
102
|
+
args1.should == {"bus_rider_app_key"=>"app3", "x" => "y", "bus_event_type" => "event5", "bus_rider_sub_key"=>"event5", "bus_rider_queue" => "default"}.merge(bus_attrs)
|
103
|
+
|
104
|
+
hash2["class"].should == "QueueBus::Worker"
|
105
|
+
args2.should == {"bus_rider_app_key"=>"app3", "x" => "y", "bus_event_type" => "event5", "bus_rider_sub_key"=>"event[45]", "bus_rider_queue" => "default"}.merge(bus_attrs)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|