resque-bus 0.2.3

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.
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Redis Connection" do
4
+ it "should use the one specified if given" do
5
+ ResqueBus.redis = "localhost:9379"
6
+ ResqueBus.redis.instance_variable_get("@redis").client.port.should == 9379
7
+ Resque.redis.instance_variable_get("@redis").client.port.should == 6379
8
+ end
9
+ it "should use the default Resque connection if none specified" do
10
+ ResqueBus.redis.instance_variable_get("@redis").client.port.should == 6379
11
+ Resque.redis.instance_variable_get("@redis").client.port.should == 6379
12
+ end
13
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ module ResqueBus
4
+ describe Rider do
5
+ it "should call execute" do
6
+ ResqueBus.should_receive(:dispatcher_execute)
7
+ Rider.perform("bus_rider_app_key" => "app", "bus_rider_sub_key" => "sub", "ok" => true, "bus_event_type" => "event_name")
8
+ end
9
+
10
+ it "should change the value" do
11
+ ResqueBus.dispatch("r1") do
12
+ subscribe "event_name" do |attributes|
13
+ Runner1.run(attributes)
14
+ end
15
+ end
16
+ Runner1.value.should == 0
17
+ Rider.perform("bus_rider_app_key" => "r1", "bus_rider_sub_key" => "event_name", "ok" => true, "bus_event_type" => "event_name")
18
+ Rider.perform("bus_rider_app_key" => "other", "bus_rider_sub_key" => "event_name", "ok" => true, "bus_event_type" => "event_name")
19
+ Runner1.value.should == 1
20
+ end
21
+
22
+
23
+ context "Integration Test" do
24
+ before(:each) do
25
+ Resque.redis = "example.com/bad"
26
+ ResqueBus.original_redis = Resque.redis
27
+ ResqueBus.redis = "localhost:6379"
28
+
29
+
30
+ ResqueBus.enqueue_to("testing", "::ResqueBus::Rider", { "bus_rider_app_key" => "r2", "bus_rider_sub_key" => "event_name", "bus_event_type" => "event_name", "ok" => true, "bus_rider_queue" => "testing" })
31
+
32
+ # like the job does
33
+ Resque.redis = ResqueBus.redis
34
+
35
+ @worker = Resque::Worker.new(:testing)
36
+ @worker.register_worker
37
+ end
38
+
39
+ it "should use the app's redis within the rider" do
40
+ host = Resque.redis.instance_variable_get("@redis").instance_variable_get("@client").host
41
+ host.should == "localhost"
42
+
43
+ ResqueBus.dispatch("r2") do
44
+ subscribe "event_name" do |attributes|
45
+ host = Resque.redis.instance_variable_get("@redis").instance_variable_get("@client").host
46
+ if host == "example.com"
47
+ Runner1.run(attributes)
48
+ end
49
+ end
50
+ end
51
+
52
+ host = Resque.redis.instance_variable_get("@redis").instance_variable_get("@client").host
53
+ host.should == "localhost"
54
+
55
+
56
+ Runner1.value.should == 0
57
+ perform_next_job @worker
58
+ Runner1.value.should == 1
59
+ end
60
+
61
+ it "should put it in the failed jobs" do
62
+
63
+ ResqueBus.dispatch("r2") do
64
+ subscribe "event_name" do |attributes|
65
+ raise "boo!"
66
+ end
67
+ end
68
+
69
+ perform_next_job @worker
70
+ Resque.info[:processed].should == 1
71
+ Resque.info[:failed].should == 1
72
+ Resque.info[:pending].should == 1 # requeued
73
+
74
+ perform_next_job @worker
75
+ Resque.info[:processed].should == 2
76
+ Resque.info[:failed].should == 2
77
+ Resque.info[:pending].should == 0
78
+ end
79
+ end
80
+
81
+
82
+ end
83
+ end
@@ -0,0 +1,75 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'timecop'
4
+
5
+ require 'resque-bus'
6
+
7
+ module ResqueBus
8
+ class Runner
9
+ def self.value
10
+ @value ||= 0
11
+ end
12
+
13
+ def self.attributes
14
+ @attributes
15
+ end
16
+
17
+ def self.run(attrs)
18
+ @value ||= 0
19
+ @value += 1
20
+ @attributes = attrs
21
+ end
22
+
23
+ def self.reset
24
+ @value = nil
25
+ @attributes = nil
26
+ end
27
+ end
28
+
29
+ class Runner1 < Runner
30
+ end
31
+
32
+ class Runner2 < Runner
33
+ end
34
+ end
35
+
36
+ def perform_next_job(worker, &block)
37
+ return unless job = @worker.reserve
38
+ @worker.perform(job, &block)
39
+ @worker.done_working
40
+ end
41
+
42
+ def test_sub(event_name, queue="default")
43
+ matcher = {"bus_event_type" => event_name}
44
+ ResqueBus::Subscription.new(queue, event_name, "::ResqueBus::Rider", matcher, nil)
45
+ end
46
+
47
+ def test_list(*args)
48
+ out = ResqueBus::SubscriptionList.new
49
+ args.each do |sub|
50
+ out.add(sub)
51
+ end
52
+ out
53
+ end
54
+
55
+
56
+ Resque::Scheduler.mute = true
57
+
58
+ RSpec.configure do |config|
59
+ config.mock_framework = :rspec
60
+
61
+ config.before(:each) do
62
+ ResqueBus.send(:reset)
63
+ end
64
+ config.after(:each) do
65
+ begin
66
+ ResqueBus.redis.flushall
67
+ rescue
68
+ end
69
+ ResqueBus.send(:reset)
70
+ ResqueBus::Runner1.reset
71
+ ResqueBus::Runner2.reset
72
+ end
73
+ end
74
+
75
+ ResqueBus.redis.namespace = "resquebus_test"
@@ -0,0 +1,233 @@
1
+ require 'spec_helper'
2
+
3
+ class SubscriberTest1
4
+ include ResqueBus::Subscriber
5
+ @queue = "myqueue"
6
+
7
+ application :my_thing
8
+ subscribe :thing_filter, :x => "y"
9
+ subscribe :event_sub
10
+
11
+ def event_sub(attributes)
12
+ ResqueBus::Runner1.run(attributes)
13
+ end
14
+
15
+ def thing_filter(attributes)
16
+ ResqueBus::Runner2.run(attributes)
17
+ end
18
+ end
19
+
20
+ class SubscriberTest2
21
+ include ResqueBus::Subscriber
22
+ application :test2
23
+ subscribe :test2, "value" => :present
24
+ transform :make_an_int
25
+
26
+ def self.make_an_int(attributes)
27
+ attributes["value"].to_s.length
28
+ end
29
+
30
+ def test2(int)
31
+ ResqueBus::Runner1.run("transformed"=>int)
32
+ end
33
+ end
34
+
35
+ module SubModule
36
+ class SubscriberTest3
37
+ include ResqueBus::Subscriber
38
+
39
+ subscribe_queue :sub_queue1, :test3, :bus_event_type => "the_event"
40
+ subscribe_queue :sub_queue2, :the_event
41
+ subscribe :other, :bus_event_type => "other_event"
42
+
43
+ def test3(attributes)
44
+ ResqueBus::Runner1.run(attributes)
45
+ end
46
+
47
+ def the_event(attributes)
48
+ ResqueBus::Runner2.run(attributes)
49
+ end
50
+ end
51
+
52
+ class SubscriberTest4
53
+ include ResqueBus::Subscriber
54
+
55
+ subscribe_queue :sub_queue1, :test4
56
+ end
57
+ end
58
+
59
+ module ResqueBus
60
+ describe Subscriber do
61
+ let(:attributes) { {"x" => "y"} }
62
+ let(:bus_attrs) { {"bus_driven_at" => Time.now.to_i} }
63
+
64
+ before(:each) do
65
+ ResqueBus::TaskManager.new(false).subscribe!
66
+ end
67
+
68
+ it "should have the application" do
69
+ SubscriberTest1.app_key.should == "my_thing"
70
+ SubModule::SubscriberTest3.app_key.should == "sub_module"
71
+ SubModule::SubscriberTest4.app_key.should == "sub_module"
72
+ end
73
+
74
+ it "should be able to transform the attributes" do
75
+ dispatcher = ResqueBus.dispatcher_by_key("test2")
76
+ all = dispatcher.subscriptions.all
77
+ all.size.should == 1
78
+
79
+ sub = all.first
80
+ sub.queue_name.should == "test2_default"
81
+ sub.class_name.should == "SubscriberTest2"
82
+ sub.key.should == "SubscriberTest2.test2"
83
+ sub.matcher.filters.should == {"value"=>"bus_special_value_present"}
84
+
85
+ Driver.perform(attributes.merge("bus_event_type" => "something2", "value"=>"nice"))
86
+
87
+ hash = JSON.parse(ResqueBus.redis.lpop("queue:test2_default"))
88
+ hash["class"].should == "SubscriberTest2"
89
+ hash["args"].should == [ {"bus_rider_app_key"=>"test2", "bus_rider_sub_key"=>"SubscriberTest2.test2", "bus_rider_queue" => "test2_default", "bus_rider_class_name"=>"SubscriberTest2",
90
+ "bus_event_type" => "something2", "value"=>"nice", "x"=>"y"}.merge(bus_attrs) ]
91
+
92
+ Runner1.value.should == 0
93
+ Runner2.value.should == 0
94
+ Util.constantize(hash["class"]).perform(*hash["args"])
95
+ Runner1.value.should == 1
96
+ Runner2.value.should == 0
97
+
98
+ Runner1.attributes.should == {"transformed" => 4}
99
+
100
+
101
+ Driver.perform(attributes.merge("bus_event_type" => "something2", "value"=>"12"))
102
+
103
+ hash = JSON.parse(ResqueBus.redis.lpop("queue:test2_default"))
104
+ hash["class"].should == "SubscriberTest2"
105
+ hash["args"].should == [ {"bus_rider_app_key"=>"test2", "bus_rider_sub_key"=>"SubscriberTest2.test2", "bus_rider_queue" => "test2_default", "bus_rider_class_name"=>"SubscriberTest2",
106
+ "bus_event_type" => "something2", "value"=>"12", "x"=>"y"}.merge(bus_attrs) ]
107
+
108
+ Runner1.value.should == 1
109
+ Runner2.value.should == 0
110
+ Util.constantize(hash["class"]).perform(*hash["args"])
111
+ Runner1.value.should == 2
112
+ Runner2.value.should == 0
113
+
114
+ Runner1.attributes.should == {"transformed" => 2}
115
+ end
116
+
117
+
118
+ it "should put in a different queue" do
119
+ dispatcher = ResqueBus.dispatcher_by_key("sub_module")
120
+ all = dispatcher.subscriptions.all
121
+ all.size.should == 4
122
+
123
+ sub = all.select{ |s| s.key == "SubModule::SubscriberTest3.test3"}.first
124
+ sub.queue_name.should == "sub_queue1"
125
+ sub.class_name.should == "SubModule::SubscriberTest3"
126
+ sub.key.should == "SubModule::SubscriberTest3.test3"
127
+ sub.matcher.filters.should == {"bus_event_type"=>"the_event"}
128
+
129
+ sub = all.select{ |s| s.key == "SubModule::SubscriberTest3.the_event"}.first
130
+ sub.queue_name.should == "sub_queue2"
131
+ sub.class_name.should == "SubModule::SubscriberTest3"
132
+ sub.key.should == "SubModule::SubscriberTest3.the_event"
133
+ sub.matcher.filters.should == {"bus_event_type"=>"the_event"}
134
+
135
+ sub = all.select{ |s| s.key == "SubModule::SubscriberTest3.other"}.first
136
+ sub.queue_name.should == "sub_module_default"
137
+ sub.class_name.should == "SubModule::SubscriberTest3"
138
+ sub.key.should == "SubModule::SubscriberTest3.other"
139
+ sub.matcher.filters.should == {"bus_event_type"=>"other_event"}
140
+
141
+ sub = all.select{ |s| s.key == "SubModule::SubscriberTest4.test4"}.first
142
+ sub.queue_name.should == "sub_queue1"
143
+ sub.class_name.should == "SubModule::SubscriberTest4"
144
+ sub.key.should == "SubModule::SubscriberTest4.test4"
145
+ sub.matcher.filters.should == {"bus_event_type"=>"test4"}
146
+
147
+ Driver.perform(attributes.merge("bus_event_type" => "the_event"))
148
+
149
+ hash = JSON.parse(ResqueBus.redis.lpop("queue:sub_queue1"))
150
+ hash["class"].should == "SubModule::SubscriberTest3"
151
+ hash["args"].should == [ {"bus_rider_app_key"=>"sub_module", "bus_rider_sub_key"=>"SubModule::SubscriberTest3.test3", "bus_rider_queue" => "sub_queue1", "bus_rider_class_name"=>"SubModule::SubscriberTest3",
152
+ "bus_event_type" => "the_event", "x" => "y"}.merge(bus_attrs) ]
153
+
154
+ Runner1.value.should == 0
155
+ Runner2.value.should == 0
156
+ Util.constantize(hash["class"]).perform(*hash["args"])
157
+ Runner1.value.should == 1
158
+ Runner2.value.should == 0
159
+
160
+ hash = JSON.parse(ResqueBus.redis.lpop("queue:sub_queue2"))
161
+ hash["class"].should == "SubModule::SubscriberTest3"
162
+ hash["args"].should == [ {"bus_rider_app_key"=>"sub_module", "bus_rider_sub_key"=>"SubModule::SubscriberTest3.the_event", "bus_rider_queue" => "sub_queue2", "bus_rider_class_name"=>"SubModule::SubscriberTest3",
163
+ "bus_event_type" => "the_event", "x" => "y"}.merge(bus_attrs) ]
164
+
165
+ Runner1.value.should == 1
166
+ Runner2.value.should == 0
167
+ Util.constantize(hash["class"]).perform(*hash["args"])
168
+ Runner1.value.should == 1
169
+ Runner2.value.should == 1
170
+ end
171
+
172
+ it "should subscribe to default and attributes" do
173
+ dispatcher = ResqueBus.dispatcher_by_key("my_thing")
174
+ all = dispatcher.subscriptions.all
175
+
176
+ sub = all.select{ |s| s.key == "SubscriberTest1.event_sub"}.first
177
+ sub.queue_name.should == "myqueue"
178
+ sub.class_name.should == "SubscriberTest1"
179
+ sub.key.should == "SubscriberTest1.event_sub"
180
+ sub.matcher.filters.should == {"bus_event_type"=>"event_sub"}
181
+
182
+ sub = all.select{ |s| s.key == "SubscriberTest1.thing_filter"}.first
183
+ sub.queue_name.should == "myqueue"
184
+ sub.class_name.should == "SubscriberTest1"
185
+ sub.key.should == "SubscriberTest1.thing_filter"
186
+ sub.matcher.filters.should == {"x"=>"y"}
187
+
188
+ Driver.perform(attributes.merge("bus_event_type" => "event_sub"))
189
+ ResqueBus.redis.smembers("queues").should =~ ["myqueue"]
190
+
191
+ hash = JSON.parse(ResqueBus.redis.lpop("queue:myqueue"))
192
+ hash["class"].should == "SubscriberTest1"
193
+ hash["args"].should == [ {"bus_rider_app_key"=>"my_thing", "bus_rider_sub_key"=>"SubscriberTest1.event_sub", "bus_rider_queue" => "myqueue", "bus_rider_class_name"=>"SubscriberTest1",
194
+ "bus_event_type" => "event_sub", "x" => "y"}.merge(bus_attrs) ]
195
+
196
+ Runner1.value.should == 0
197
+ Runner2.value.should == 0
198
+ Util.constantize(hash["class"]).perform(*hash["args"])
199
+ Runner1.value.should == 1
200
+ Runner2.value.should == 0
201
+
202
+ hash = JSON.parse(ResqueBus.redis.lpop("queue:myqueue"))
203
+ hash["class"].should == "SubscriberTest1"
204
+ hash["args"].should == [ {"bus_rider_app_key"=>"my_thing", "bus_rider_sub_key"=>"SubscriberTest1.thing_filter", "bus_rider_queue" => "myqueue", "bus_rider_class_name"=>"SubscriberTest1",
205
+ "bus_event_type" => "event_sub", "x" => "y"}.merge(bus_attrs) ]
206
+
207
+ Runner1.value.should == 1
208
+ Runner2.value.should == 0
209
+ Util.constantize(hash["class"]).perform(*hash["args"])
210
+ Runner1.value.should == 1
211
+ Runner2.value.should == 1
212
+
213
+ Driver.perform(attributes.merge("bus_event_type" => "event_sub_other"))
214
+ ResqueBus.redis.smembers("queues").should =~ ["myqueue"]
215
+
216
+ hash = JSON.parse(ResqueBus.redis.lpop("queue:myqueue"))
217
+ hash["class"].should == "SubscriberTest1"
218
+ hash["args"].should == [ {"bus_rider_app_key"=>"my_thing", "bus_rider_sub_key"=>"SubscriberTest1.thing_filter", "bus_rider_queue" => "myqueue", "bus_rider_class_name"=>"SubscriberTest1",
219
+ "bus_event_type" => "event_sub_other", "x" => "y"}.merge(bus_attrs) ]
220
+
221
+ Runner1.value.should == 1
222
+ Runner2.value.should == 1
223
+ Util.constantize(hash["class"]).perform(*hash["args"])
224
+ Runner1.value.should == 1
225
+ Runner2.value.should == 2
226
+
227
+ Driver.perform({"x"=>"z"}.merge("bus_event_type" => "event_sub_other"))
228
+ ResqueBus.redis.smembers("queues").should =~ ["myqueue"]
229
+
230
+ ResqueBus.redis.lpop("queue:myqueue").should be_nil
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ module ResqueBus
4
+ describe SubscriptionList do
5
+ describe ".from_redis" do
6
+ it "should return from attributes" do
7
+ mult = {"event_one" => {"class" => "MyClass", "queue_name" => "default", "key" => "event_one", "matcher" => {"bus_event_type" => "event_one"}},
8
+ "event_two" => {"class" => "MyClass", "queue_name" => "else", "key" => "event_two", "matcher" => {"bus_event_type" => "event_two"}}}
9
+
10
+ list = SubscriptionList.from_redis(mult)
11
+ list.size.should == 2
12
+ one = list.key("event_one")
13
+ two = list.key("event_two")
14
+
15
+ one.key.should == "event_one"
16
+ one.key.should == "event_one"
17
+ one.queue_name.should == "default"
18
+ one.class_name.should == "MyClass"
19
+ one.matcher.filters.should == {"bus_event_type" => "event_one"}
20
+
21
+ two.key.should == "event_two"
22
+ two.key.should == "event_two"
23
+ two.queue_name.should == "else"
24
+ two.class_name.should == "MyClass"
25
+ two.matcher.filters.should == {"bus_event_type" => "event_two"}
26
+ end
27
+ end
28
+
29
+ describe "#to_redis" do
30
+ it "should generate what to store" do
31
+ list = SubscriptionList.new
32
+ list.add(Subscription.new("default", "key1", "MyClass", {"bus_event_type" => "event_one"}))
33
+ list.add(Subscription.new("else_ok", "key2", "MyClass", {"bus_event_type" => "event_two"}))
34
+
35
+ hash = list.to_redis
36
+ hash.should == { "key1" => {"queue_name" => "default", "key" => "key1", "class" => "MyClass", "matcher" => {"bus_event_type" => "event_one"}},
37
+ "key2" => {"queue_name" => "else_ok", "key" => "key2", "class" => "MyClass", "matcher" => {"bus_event_type" => "event_two"}}
38
+ }
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ module ResqueBus
4
+ describe Subscription do
5
+ it "should normalize the queue name" do
6
+ Subscription.new("test", "my_event", "MyClass", {}, nil).queue_name.should == "test"
7
+ Subscription.new("tes t", "my_event", "MyClass", {}, nil).queue_name.should == "tes_t"
8
+ Subscription.new("t%s", "my_event", "MyClass", {}, nil).queue_name.should == "t_s"
9
+ end
10
+
11
+ describe ".register" do
12
+ it "should take in args from dispatcher" do
13
+ executor = Proc.new { |attributes| }
14
+ sub = Subscription.register("queue_name", "mykey", "MyClass", {"bus_event_type" => "my_event"}, executor)
15
+ sub.send(:executor).should == executor
16
+ sub.matcher.filters.should == {"bus_event_type" => "my_event"}
17
+ sub.queue_name.should == "queue_name"
18
+ sub.key.should == "mykey"
19
+ sub.class_name.should == "MyClass"
20
+ end
21
+ end
22
+
23
+ describe "#execute!" do
24
+ it "should call the executor with the attributes" do
25
+ exec = Object.new
26
+ exec.should_receive(:call)
27
+
28
+ sub = Subscription.new("x", "y", "ClassName", {}, exec)
29
+ sub.execute!({"ok" => true})
30
+ end
31
+ end
32
+
33
+ describe "#to_redis" do
34
+ it "should return what to store for this subscription" do
35
+ sub = Subscription.new("queue_one", "xyz", "ClassName", {"bus_event_type" => "my_event"}, nil)
36
+ sub.to_redis.should == {"queue_name" => "queue_one", "key" => "xyz", "class" => "ClassName", "matcher" => {"bus_event_type" => "my_event"}}
37
+ end
38
+ end
39
+
40
+ describe "#matches?" do
41
+ it "should do pattern stuff" do
42
+ Subscription.new("x", "id", "ClassName", {"bus_event_type" => "one"}).matches?("bus_event_type" => "one").should == true
43
+ Subscription.new("x", "id", "ClassName", {"bus_event_type" => "one"}).matches?("bus_event_type" => "onex").should == false
44
+ Subscription.new("x", "id", "ClassName", {"bus_event_type" => "^one.*$"}).matches?("bus_event_type" => "onex").should == true
45
+ Subscription.new("x", "id", "ClassName", {"bus_event_type" => "one.*"}).matches?("bus_event_type" => "onex").should == true
46
+ Subscription.new("x", "id", "ClassName", {"bus_event_type" => "one.?"}).matches?("bus_event_type" => "onex").should == true
47
+ Subscription.new("x", "id", "ClassName", {"bus_event_type" => "one.?"}).matches?("bus_event_type" => "one").should == true
48
+ Subscription.new("x", "id", "ClassName", {"bus_event_type" => "\\"}).matches?("bus_event_type" => "one").should == false
49
+ end
50
+ end
51
+
52
+ end
53
+ end