worker_roulette 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NzQ2MGVkMWQ0ZDcwYTQzOGM0OGJlMDM5M2I1OGU2YjkzZTU2MzIzZA==
4
+ M2EzZmZkYTllZGYwMjA1MDI1MzVmZDU5ODk1ZGRiNzYzMjQzMjQ1OQ==
5
5
  data.tar.gz: !binary |-
6
- Mjc3ZTk1YTJjOWMxMzYyNmE3YTdhNTNiZjM4ZWRhMTEwN2ZjNjAxNA==
6
+ NDZmNjhjMTJjZDJhMjJlNzI5MjE2MjllZjFkMGQ1ZDIxODExNTQ4NQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NjA4NmI3NTc1M2MwNjg3N2FmZDIxNjIyZGQ1YjA4NTFjMzBlNzVmZDhhNjZi
10
- ZWU5NjI5NmY1MmYzZWFjNTZjOWY5OTRhMGZkNzY3ODVjNDVhN2ViOGEzZGE2
11
- NzU3MDdiYmM4MzY1YjU2NDI0YjFlMGU0NjAzYWY0ZDNmMjdjNDg=
9
+ NjAyNTBlZDUxNmM5M2Y1MGMwMGYyNzdkNDUzNDEzMGQxNTI0ODY4NTlhY2U1
10
+ YjRiYjQ1MWI3YzMxNDdmZWM3ZjE1Y2ViZDg1M2FhYTA1ZjhmYzNhYWYwMjY2
11
+ ZThkODM4ZjY0MmE5NzlmMTdlZTRiMzRhMzUwMWFjMGJkM2NlYTU=
12
12
  data.tar.gz: !binary |-
13
- MjE2Nzc5YmE3MDBhZWQ5YjdmMzdmNDZlY2U4ZmQ3NmI2NzQ4OTFkNjFjNDZj
14
- YjU2M2M0MmViZjdiN2I0ZDE0MGJmZjk3YmQ3NWMxZjk5ZGMxY2MzNGM3MzMz
15
- NmRlMzJlMmNmZTg0YjA2ODRiYjI3Njk5NzUyY2U5MTAxMGY5ZTM=
13
+ ODUxMmQwNWNhOWI5NTBkMmQ2NzFlMzUzY2Q4NjZlZTYzZDE4ZmQ2NGZiODJk
14
+ ZWNkMzc3ZmUxY2UzOTk4OTJjZjlmNDZkMjU4N2Y3ZGVjMmUzYzIxOTdmMzg2
15
+ MDJlZjAzNGFiN2JjMGMzNWEwYWVlNmY3OTQ4MjE0NjliY2ViOTE=
data/.gitignore CHANGED
@@ -16,4 +16,6 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  tmp/*
19
- coverage/*
19
+ coverage/*
20
+ vendor/bundle
21
+ results.xml
data/Gemfile CHANGED
@@ -2,3 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in worker_roulette.gemspec
4
4
  gemspec
5
+
6
+ # Gemfile
7
+ group :development do
8
+ gem 'evented-spec', :git => 'https://github.com/ruby-amqp/evented-spec.git'
9
+ end
@@ -1,6 +1,8 @@
1
1
  require_relative './tradesman'
2
2
  module WorkerRoulette
3
3
  class ATradesman < Tradesman
4
+ attr_reader :timer
5
+
4
6
  def wait_for_work_orders(on_subscribe_callback = nil, &on_message_callback)
5
7
  @redis_pubsub ||= WorkerRoulette.new_redis_pubsub #cannot use connection pool bc redis expects each obj to own its own pubsub connection for the life of the subscription
6
8
  @redis_pubsub.on(:subscribe) {|channel, subscription_count| on_subscribe_callback.call(channel, subscription_count) if on_subscribe_callback}
@@ -23,8 +25,8 @@ module WorkerRoulette
23
25
  end
24
26
  end
25
27
 
26
- private
27
- attr_reader :timer
28
+ private
29
+
28
30
  def get_messages(message, channel, on_message_callback)
29
31
  return unless on_message_callback
30
32
  work_orders! do |work_orders_1|
@@ -2,6 +2,34 @@ module WorkerRoulette
2
2
  class Foreman
3
3
  attr_reader :sender
4
4
 
5
+ LUA_ENQUEUE_WORK_ORDERS = <<-HERE
6
+ local counter_key = KEYS[1]
7
+ local job_board_key = KEYS[2]
8
+ local sender_key = KEYS[3]
9
+ local channel = KEYS[4]
10
+
11
+ local work_order = ARGV[1]
12
+ local job_notification = ARGV[2]
13
+ local redis_call = redis.call
14
+ local zscore = 'ZSCORE'
15
+ local incr = 'INCR'
16
+ local zadd = 'ZADD'
17
+ local rpush = 'RPUSH'
18
+ local publish = 'PUBLISH'
19
+
20
+ local function enqueue_work_orders(work_order, job_notification)
21
+ if (redis_call(zscore, job_board_key, sender_key) == false) then
22
+ local count = redis_call(incr, counter_key)
23
+ redis_call(zadd, job_board_key, count, sender_key)
24
+ end
25
+
26
+ redis_call(rpush,sender_key, work_order)
27
+ redis_call(publish, channel, job_notification)
28
+ end
29
+
30
+ enqueue_work_orders(work_order, job_notification)
31
+ HERE
32
+
5
33
  def initialize(sender, redis_pool, namespace = nil)
6
34
  @sender = sender
7
35
  @namespace = namespace
@@ -16,7 +44,7 @@ module WorkerRoulette
16
44
 
17
45
  def enqueue_work_order_without_headers(work_order, &callback)
18
46
  Lua.call(self.class.lua_enqueue_work_orders, [counter_key, job_board_key, sender_key, @channel],
19
- [WorkerRoulette.dump(work_order), WorkerRoulette::JOB_NOTIFICATIONS], &callback)
47
+ [WorkerRoulette.dump(work_order), WorkerRoulette::JOB_NOTIFICATIONS], &callback)
20
48
  end
21
49
 
22
50
  def job_board_key
@@ -27,7 +55,8 @@ module WorkerRoulette
27
55
  @counter_key ||= WorkerRoulette.counter_key(@namespace)
28
56
  end
29
57
 
30
- private
58
+ private
59
+
31
60
  def sender_key
32
61
  @sender_key = WorkerRoulette.sender_key(sender, @namespace)
33
62
  end
@@ -37,33 +66,7 @@ module WorkerRoulette
37
66
  end
38
67
 
39
68
  def self.lua_enqueue_work_orders
40
- <<-HERE
41
- local counter_key = KEYS[1]
42
- local job_board_key = KEYS[2]
43
- local sender_key = KEYS[3]
44
- local channel = KEYS[4]
45
-
46
- local work_order = ARGV[1]
47
- local job_notification = ARGV[2]
48
- local redis_call = redis.call
49
- local zscore = 'ZSCORE'
50
- local incr = 'INCR'
51
- local zadd = 'ZADD'
52
- local rpush = 'RPUSH'
53
- local publish = 'PUBLISH'
54
-
55
- local function enqueue_work_orders(work_order, job_notification)
56
- if (redis_call(zscore, job_board_key, sender_key) == false) then
57
- local count = redis_call(incr, counter_key)
58
- redis_call(zadd, job_board_key, count, sender_key)
59
- end
60
-
61
- redis_call(rpush,sender_key, work_order)
62
- redis_call(publish, channel, job_notification)
63
- end
64
-
65
- enqueue_work_orders(work_order, job_notification)
66
- HERE
69
+ LUA_ENQUEUE_WORK_ORDERS
67
70
  end
68
71
  end
69
- end
72
+ end
@@ -1,43 +1,8 @@
1
1
  module WorkerRoulette
2
2
  class Tradesman
3
3
  attr_reader :last_sender
4
- def initialize(client_pool, pubsub_pool, namespace = nil)
5
- @client_pool = client_pool
6
- @pubsub_pool = pubsub_pool
7
- @namespace = namespace
8
- @channel = namespace || WorkerRoulette::JOB_NOTIFICATIONS
9
- end
10
-
11
- def wait_for_work_orders(on_subscribe_callback = nil, &block)
12
- @pubsub_pool.with do |redis|
13
- redis.subscribe(@channel) do |on|
14
- on.subscribe {on_subscribe_callback.call if on_subscribe_callback}
15
- on.message {block.call(work_orders! + work_orders!) if block}
16
- end
17
- end
18
- end
19
-
20
- def work_orders!(&callback)
21
- Lua.call(self.class.lua_drain_work_orders, [job_board_key, @last_sender], [nil]) do |results|
22
- results ||= []
23
- @last_sender = (results.first || '').split(':').first
24
- work = (results[1] || []).map {|work_order| WorkerRoulette.load(work_order)}
25
- callback.call work if callback
26
- work
27
- end
28
- end
29
-
30
- def unsubscribe
31
- @pubsub_pool.with {|redis| redis.unsubscribe(@channel)}
32
- end
33
4
 
34
- def job_board_key
35
- @job_board_key ||= WorkerRoulette.job_board_key(@namespace)
36
- end
37
-
38
- private
39
- def self.lua_drain_work_orders
40
- <<-HERE
5
+ LUA_DRAIN_WORK_ORDERS = <<-HERE
41
6
  local empty_string = ""
42
7
  local job_board_key = KEYS[1]
43
8
  local last_sender_key = KEYS[2] or empty_string
@@ -88,7 +53,46 @@ module WorkerRoulette
88
53
  end
89
54
 
90
55
  return drain_work_orders(job_board_key, last_sender_key, empty_string)
91
- HERE
56
+ HERE
57
+
58
+ def initialize(client_pool, pubsub_pool, namespace = nil)
59
+ @client_pool = client_pool
60
+ @pubsub_pool = pubsub_pool
61
+ @namespace = namespace
62
+ @channel = namespace || WorkerRoulette::JOB_NOTIFICATIONS
63
+ end
64
+
65
+ def wait_for_work_orders(on_subscribe_callback = nil, &block)
66
+ @pubsub_pool.with do |redis|
67
+ redis.subscribe(@channel) do |on|
68
+ on.subscribe {on_subscribe_callback.call if on_subscribe_callback}
69
+ on.message {block.call(work_orders! + work_orders!) if block}
70
+ end
71
+ end
72
+ end
73
+
74
+ def work_orders!(&callback)
75
+ Lua.call(self.class.lua_drain_work_orders, [job_board_key, @last_sender], [nil]) do |results|
76
+ results ||= []
77
+ @last_sender = (results.first || '').split(':').first
78
+ work = (results[1] || []).map {|work_order| WorkerRoulette.load(work_order)}
79
+ callback.call work if callback
80
+ work
81
+ end
82
+ end
83
+
84
+ def unsubscribe
85
+ @pubsub_pool.with {|redis| redis.unsubscribe(@channel)}
86
+ end
87
+
88
+ def job_board_key
89
+ @job_board_key ||= WorkerRoulette.job_board_key(@namespace)
90
+ end
91
+
92
+ private
93
+
94
+ def self.lua_drain_work_orders
95
+ LUA_DRAIN_WORK_ORDERS
92
96
  end
93
97
  end
94
- end
98
+ end
@@ -1,3 +1,3 @@
1
1
  module WorkerRoulette
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
3
3
  end
@@ -13,7 +13,7 @@ module WorkerRoulette
13
13
  JOB_NOTIFICATIONS = "new_job_ready"
14
14
 
15
15
  def self.start(config = {})
16
- @redis_config = {host: 'localhost', port: 6379, db: 14, driver: :hiredis, timeout: 5, evented: false, pool_size: 10}.merge(config)
16
+ @redis_config = { host: 'localhost', port: 6379, db: 14, driver: :hiredis, timeout: 5, evented: false, pool_size: 10 }.merge(config)
17
17
  @pool_config = Hash[size: @redis_config.delete(:pool_size), timeout: @redis_config.delete(:timeout)]
18
18
  @evented = @redis_config.delete(:evented)
19
19
 
@@ -80,7 +80,9 @@ module WorkerRoulette
80
80
  def self.counter_key(sender, namespace = nil)
81
81
  "#{namespace + ':' if namespace}counter_key"
82
82
  end
83
- private
83
+
84
+ private
85
+
84
86
  def self.new_redis
85
87
  if @evented
86
88
  require 'eventmachine'
@@ -93,7 +95,7 @@ private
93
95
 
94
96
  def self.new_redis_pubsub
95
97
  if @evented
96
- new_redis.pubsub
98
+ new_redis.pubsub
97
99
  else
98
100
  new_redis
99
101
  end
@@ -20,19 +20,20 @@ describe WorkerRoulette do
20
20
  context "Evented Foreman" do
21
21
  let(:subject) {WorkerRoulette.a_foreman(sender)}
22
22
 
23
- it "should enqueue work" do
23
+ it "enqueues work" do
24
24
  called = false
25
- foreman = WorkerRoulette.a_foreman('foreman')
25
+ foreman = WorkerRoulette.a_foreman('foreman')
26
26
  foreman.enqueue_work_order('some old fashion work') do |redis_response, stuff|
27
27
  called = true
28
28
  end
29
- done(0.1) {called.should == true}
29
+ done(0.1) { expect(called).to be_truthy }
30
30
  end
31
31
 
32
32
  it "should enqueue_work_order two work_orders in the sender's slot in the job board" do
33
33
  subject.enqueue_work_order(work_orders.first) do
34
34
  subject.enqueue_work_order(work_orders.last) do
35
- redis.lrange(sender, 0, -1).should == work_orders.map {|m| WorkerRoulette.dump(default_headers.merge({'payload' => m})) }
35
+ expected = work_orders.map { |m| WorkerRoulette.dump(default_headers.merge({'payload' => m})) }
36
+ expect(redis.lrange(sender, 0, -1)).to eq(expected)
36
37
  done
37
38
  end
38
39
  end
@@ -40,14 +41,14 @@ describe WorkerRoulette do
40
41
 
41
42
  it "should enqueue_work_order an array of work_orders without headers in the sender's slot in the job board" do
42
43
  subject.enqueue_work_order_without_headers(work_orders) do
43
- redis.lrange(sender, 0, -1).should == [WorkerRoulette.dump(work_orders)]
44
+ expect(redis.lrange(sender, 0, -1)).to eq([WorkerRoulette.dump(work_orders)])
44
45
  done
45
46
  end
46
47
  end
47
48
 
48
49
  it "should enqueue_work_order an array of work_orders with default headers in the sender's slot in the job board" do
49
50
  subject.enqueue_work_order(work_orders) do
50
- redis.lrange(sender, 0, -1).should == jsonized_work_orders_with_headers
51
+ expect(redis.lrange(sender, 0, -1)).to eq(jsonized_work_orders_with_headers)
51
52
  done
52
53
  end
53
54
  end
@@ -56,7 +57,7 @@ describe WorkerRoulette do
56
57
  extra_headers = {'foo' => 'bars'}
57
58
  subject.enqueue_work_order(work_orders, extra_headers) do
58
59
  work_orders_with_headers['headers'].merge!(extra_headers)
59
- redis.lrange(sender, 0, -1).should == [WorkerRoulette.dump(work_orders_with_headers)]
60
+ expect(redis.lrange(sender, 0, -1)).to eq([WorkerRoulette.dump(work_orders_with_headers)])
60
61
  done
61
62
  end
62
63
  end
@@ -66,7 +67,7 @@ describe WorkerRoulette do
66
67
  first_foreman.enqueue_work_order('foo') do
67
68
  subject.enqueue_work_order(work_orders.first) do
68
69
  subject.enqueue_work_order(work_orders.last) do
69
- redis.zrange(subject.job_board_key, 0, -1, with_scores: true).should == [["first_foreman", 1.0], ["katie_80", 2.0]]
70
+ expect(redis.zrange(subject.job_board_key, 0, -1, with_scores: true)).to eq([["first_foreman", 1.0], ["katie_80", 2.0]])
70
71
  done
71
72
  end
72
73
  end
@@ -75,13 +76,13 @@ describe WorkerRoulette do
75
76
 
76
77
  it "should generate a monotically increasing score for senders not on the job board, but not for senders already there" do
77
78
  first_foreman = WorkerRoulette.a_foreman('first_foreman')
78
- redis.get(subject.counter_key).should == nil
79
+ expect(redis.get(subject.counter_key)).to be_nil
79
80
  first_foreman.enqueue_work_order(work_orders.first) do
80
- redis.get(subject.counter_key).should == "1"
81
+ expect(redis.get(subject.counter_key)).to eq("1")
81
82
  first_foreman.enqueue_work_order(work_orders.last) do
82
- redis.get(subject.counter_key).should == "1"
83
+ expect(redis.get(subject.counter_key)).to eq("1")
83
84
  subject.enqueue_work_order(work_orders.first) do
84
- redis.get(subject.counter_key).should == "2"
85
+ expect(redis.get(subject.counter_key)).to eq("2")
85
86
  done
86
87
  end
87
88
  end
@@ -93,7 +94,7 @@ describe WorkerRoulette do
93
94
  subscriber = WorkerRoulette.new_redis_pubsub
94
95
  subscriber.subscribe(WorkerRoulette::JOB_NOTIFICATIONS) do |message|
95
96
  subscriber.unsubscribe(WorkerRoulette::JOB_NOTIFICATIONS)
96
- message.should == WorkerRoulette::JOB_NOTIFICATIONS
97
+ expect(message).to eq(WorkerRoulette::JOB_NOTIFICATIONS)
97
98
  done
98
99
  end.callback { subject.enqueue_work_order(work_orders) }
99
100
  end
@@ -106,7 +107,7 @@ describe WorkerRoulette do
106
107
  it "should be working on behalf of a sender" do
107
108
  foreman.enqueue_work_order(work_orders) do
108
109
  subject.work_orders! do |r|
109
- subject.last_sender.should == sender
110
+ expect(subject.last_sender).to eq(sender)
110
111
  done
111
112
  end
112
113
  end
@@ -116,9 +117,9 @@ describe WorkerRoulette do
116
117
  it "should drain one set of work_orders from the sender's slot in the job board" do
117
118
  foreman.enqueue_work_order(work_orders) do
118
119
  subject.work_orders! do |r|
119
- r.should == [work_orders_with_headers]
120
- subject.work_orders! do |r| r.should == []
121
- subject.work_orders! {|r| r.should == []; done} #does not throw an error if queue is alreay empty
120
+ expect(r).to eq([work_orders_with_headers])
121
+ subject.work_orders! do |r| expect(r).to be_empty
122
+ subject.work_orders! {|r| expect(r).to be_empty; done} #does not throw an error if queue is alreay empty
122
123
  end
123
124
  end
124
125
  end
@@ -130,19 +131,19 @@ describe WorkerRoulette do
130
131
  most_recent_sender = 'most_recent_sender'
131
132
  most_recent_foreman = WorkerRoulette.a_foreman(most_recent_sender)
132
133
  most_recent_foreman.enqueue_work_order(work_orders) do
133
- redis.zrange(subject.job_board_key, 0, -1).should == [oldest_sender, most_recent_sender]
134
- subject.work_orders! { redis.zrange(subject.job_board_key, 0, -1).should == [most_recent_sender]; done }
134
+ expect(redis.zrange(subject.job_board_key, 0, -1)).to eq([oldest_sender, most_recent_sender])
135
+ subject.work_orders! { expect(redis.zrange(subject.job_board_key, 0, -1)).to eq([most_recent_sender]); done }
135
136
  end
136
137
  end
137
138
  end
138
139
 
139
140
  it "should get the work_orders from the next queue when a new job is ready" do
140
- subject.should_receive(:work_orders!).twice.and_call_original
141
+ expect(subject).to receive(:work_orders!).twice.and_call_original
141
142
  publish = proc {foreman.enqueue_work_order(work_orders)}
142
143
 
143
144
  subject.wait_for_work_orders(publish) do |redis_work_orders, message, channel|
144
- redis_work_orders.should == [work_orders_with_headers]
145
- subject.last_sender.should == nil
145
+ expect(redis_work_orders).to eq([work_orders_with_headers])
146
+ expect(subject.last_sender).to be_nil
146
147
  done
147
148
  end
148
149
  end
@@ -160,19 +161,19 @@ describe WorkerRoulette do
160
161
  good_publish = proc {good_foreman.enqueue_work_order('some old fashion work')}
161
162
  bad_publish = proc {bad_foreman.enqueue_work_order('evil biddings you should not carry out')}
162
163
 
163
- tradesman.should_receive(:work_orders!).twice.and_call_original
164
- evil_tradesman.should_receive(:work_orders!).twice.and_call_original
164
+ expect(tradesman).to receive(:work_orders!).twice.and_call_original
165
+ expect(evil_tradesman).to receive(:work_orders!).twice.and_call_original
165
166
 
166
167
  #They are double subscribing; is it possible that it is the connection pool?
167
168
 
168
169
  tradesman.wait_for_work_orders(good_publish) do |good_work|
169
- good_work.to_s.should match("old fashion")
170
- good_work.to_s.should_not match("evil")
170
+ expect(good_work.to_s).to match("old fashion")
171
+ expect(good_work.to_s).not_to match("evil")
171
172
  end
172
173
 
173
174
  evil_tradesman.wait_for_work_orders(bad_publish) do |bad_work|
174
- bad_work.to_s.should_not match("old fashion")
175
- bad_work.to_s.should match("evil")
175
+ expect(bad_work.to_s).not_to match("old fashion")
176
+ expect(bad_work.to_s).to match("evil")
176
177
  end
177
178
 
178
179
  done(0.2)
@@ -183,51 +184,49 @@ describe WorkerRoulette do
183
184
  subject.wait_for_work_orders(publish) do |redis_work_orders, message, channel|
184
185
  subject.unsubscribe {done}
185
186
  end
186
- EM::Hiredis::PubsubClient.any_instance.should_receive(:close_connection).and_call_original
187
+ expect_any_instance_of(EM::Hiredis::PubsubClient).to receive(:close_connection).and_call_original
187
188
  end
188
189
 
189
190
  it "should periodically (random time between 20 and 25 seconds?) poll the job board for new work, in case it missed a notification" do
190
- EM::PeriodicTimer.should_receive(:new) {|time| time.should be_within(2.5).of(22.5)}
191
+ expect(EM::PeriodicTimer).to receive(:new) {|time| expect(time).to be_within(2.5).of(22.5)}
191
192
  publish = proc {foreman.enqueue_work_order('foo')}
192
193
  subject.wait_for_work_orders(publish) {done}
193
194
  end
194
195
 
195
- xit "should cancel the old timer when the on_message callback is called" do
196
+ pending "cancels the old timer when the on_message callback is called" do
196
197
  publish = proc {foreman.enqueue_work_order('foo')}
197
198
  subject.wait_for_work_orders(publish) do
198
- subject.send(:timer).should_receive(:cancel).and_call_original
199
+ expect(subject.send(:timer)).to receive(:cancel).and_call_original
199
200
  done
200
201
  end
201
202
  end
202
203
 
203
204
  it "should pull off work orders for more than one sender" do
204
- tradesman = WorkerRoulette.a_tradesman('good_channel')
205
+ tradesman = WorkerRoulette.a_tradesman('good_channel')
205
206
 
206
- good_foreman = WorkerRoulette.a_foreman('good_foreman', 'good_channel')
207
- lazy_foreman = WorkerRoulette.a_foreman('lazy_foreman', 'good_channel')
207
+ good_foreman = WorkerRoulette.a_foreman('good_foreman', 'good_channel')
208
+ lazy_foreman = WorkerRoulette.a_foreman('lazy_foreman', 'good_channel')
208
209
 
209
210
  got_good = false
210
211
  got_lazy = false
211
212
  good_foreman.enqueue_work_order('do good work') do
212
213
  tradesman.work_orders! do |r|
213
214
  got_good = true
214
- r.first['payload'].should == ('do good work')
215
+ expect(r.first['payload']).to eq('do good work')
215
216
  end
216
217
  end
217
218
  lazy_foreman.enqueue_work_order('just get it done') do
218
219
  tradesman.work_orders! do |r|
219
220
  got_lazy = true
220
- r.first['payload'].should == ('just get it done')
221
+ expect(r.first['payload']).to eq('just get it done')
221
222
  end
222
223
  end
223
224
 
224
- done(0.2) {(got_good && got_lazy).should == true}
225
+ done(0.2) {expect(got_good && got_lazy).to eq(true)}
225
226
  end
226
227
  end
227
228
 
228
- xit "should return a hash with a string in the payload if OJ cannot parse the json" do
229
-
230
- end
229
+ pending "should return a hash with a string in the payload if OJ cannot parse the json"
231
230
 
232
231
  context "Failure" do
233
232
  it "should not put the sender_id and work_orders back if processing fails bc new work_orders may have been processed while that process failed" do; done; end
@@ -16,54 +16,54 @@ describe WorkerRoulette do
16
16
  end
17
17
 
18
18
  it "should exist" do
19
- WorkerRoulette.should_not be_nil
19
+ expect(WorkerRoulette).not_to be_nil
20
20
  end
21
21
 
22
22
  context Foreman do
23
23
  let(:subject) {WorkerRoulette.foreman(sender)}
24
24
 
25
25
  it "should be working on behalf of a sender" do
26
- subject.sender.should == sender
26
+ expect(subject.sender).to eq(sender)
27
27
  end
28
28
 
29
29
  it "should enqueue_work_order two work_orders in the sender's slot in the switchboard" do
30
30
  subject.enqueue_work_order(work_orders.first) {}
31
31
  subject.enqueue_work_order(work_orders.last) {}
32
- redis.lrange(sender, 0, -1).should == work_orders.map {|m| WorkerRoulette.dump(default_headers.merge({'payload' => m})) }
32
+ expect(redis.lrange(sender, 0, -1)).to eq(work_orders.map {|m| WorkerRoulette.dump(default_headers.merge({'payload' => m})) })
33
33
  end
34
34
 
35
35
  it "should enqueue_work_order an array of work_orders without headers in the sender's slot in the switchboard" do
36
36
  subject.enqueue_work_order_without_headers(work_orders)
37
- redis.lrange(sender, 0, -1).should == [WorkerRoulette.dump(work_orders)]
37
+ expect(redis.lrange(sender, 0, -1)).to eq([WorkerRoulette.dump(work_orders)])
38
38
  end
39
39
 
40
40
  it "should enqueue_work_order an array of work_orders with default headers in the sender's slot in the switchboard" do
41
41
  subject.enqueue_work_order(work_orders)
42
- redis.lrange(sender, 0, -1).should == jsonized_work_orders_with_headers
42
+ expect(redis.lrange(sender, 0, -1)).to eq(jsonized_work_orders_with_headers)
43
43
  end
44
44
 
45
45
  it "should enqueue_work_order an array of work_orders with additional headers in the sender's slot in the switchboard" do
46
46
  extra_headers = {'foo' => 'bars'}
47
47
  subject.enqueue_work_order(work_orders, extra_headers)
48
48
  work_orders_with_headers['headers'].merge!(extra_headers)
49
- redis.lrange(sender, 0, -1).should == [WorkerRoulette.dump(work_orders_with_headers)]
49
+ expect(redis.lrange(sender, 0, -1)).to eq([WorkerRoulette.dump(work_orders_with_headers)])
50
50
  end
51
51
 
52
52
  it "should post the sender's id to the job board with an order number" do
53
53
  subject.enqueue_work_order(work_orders.first)
54
54
  WorkerRoulette.foreman('other_forman').enqueue_work_order(work_orders.last)
55
- redis.zrange(subject.job_board_key, 0, -1, with_scores: true).should == [[sender, 1.0], ["other_forman", 2.0]]
55
+ expect(redis.zrange(subject.job_board_key, 0, -1, with_scores: true)).to eq([[sender, 1.0], ["other_forman", 2.0]])
56
56
  end
57
57
 
58
58
  it "should generate a monotically increasing score for senders not on the job board, but not for senders already there" do
59
59
  other_forman = WorkerRoulette.foreman('other_forman')
60
- redis.get(subject.counter_key).should == nil
60
+ expect(redis.get(subject.counter_key)).to be_nil
61
61
  subject.enqueue_work_order(work_orders.first)
62
- redis.get(subject.counter_key).should == "1"
62
+ expect(redis.get(subject.counter_key)).to eq("1")
63
63
  subject.enqueue_work_order(work_orders.last)
64
- redis.get(subject.counter_key).should == "1"
64
+ expect(redis.get(subject.counter_key)).to eq("1")
65
65
  other_forman.enqueue_work_order(work_orders.last)
66
- redis.get(other_forman.counter_key).should == "2"
66
+ expect(redis.get(other_forman.counter_key)).to eq("2")
67
67
  end
68
68
 
69
69
  it "should publish a notification that a new job is ready" do
@@ -80,7 +80,7 @@ describe WorkerRoulette do
80
80
  end
81
81
  end
82
82
 
83
- result.should == WorkerRoulette::JOB_NOTIFICATIONS
83
+ expect(result).to eq(WorkerRoulette::JOB_NOTIFICATIONS)
84
84
  end
85
85
  end
86
86
 
@@ -93,27 +93,27 @@ describe WorkerRoulette do
93
93
  end
94
94
 
95
95
  it "should have a last sender if it found messages" do
96
- subject.work_orders!.length.should == 1
97
- subject.last_sender.should == sender
96
+ expect(subject.work_orders!.length).to eq(1)
97
+ expect(subject.last_sender).to eq(sender)
98
98
  end
99
99
 
100
100
  it "should not have a last sender if it found no messages" do
101
- subject.work_orders!.length.should == 1
102
- subject.work_orders!.length.should == 0
103
- subject.last_sender.should == nil
101
+ expect(subject.work_orders!.length).to eq(1)
102
+ expect(subject.work_orders!.length).to eq(0)
103
+ expect(subject.last_sender).to be_nil
104
104
  end
105
105
 
106
106
  it "should drain one set of work_orders from the sender's slot in the switchboard" do
107
- subject.work_orders!.should == [work_orders_with_headers]
108
- subject.work_orders!.should == []
109
- subject.work_orders!.should == [] #does not throw an error if queue is alreay empty
107
+ expect(subject.work_orders!).to eq([work_orders_with_headers])
108
+ expect(subject.work_orders!).to be_empty
109
+ expect(subject.work_orders!).to be_empty #does not throw an error if queue is already empty
110
110
  end
111
111
 
112
112
  it "should drain all the work_orders from the sender's slot in the switchboard" do
113
113
  foreman.enqueue_work_order(work_orders)
114
- subject.work_orders!.should == [work_orders_with_headers, work_orders_with_headers]
115
- subject.work_orders!.should == []
116
- subject.work_orders!.should == [] #does not throw an error if queue is alreay empty
114
+ expect(subject.work_orders!).to eq([work_orders_with_headers, work_orders_with_headers])
115
+ expect(subject.work_orders!).to be_empty
116
+ expect(subject.work_orders!).to be_empty #does not throw an error if queue is already empty
117
117
  end
118
118
 
119
119
  it "should take the oldest sender off the job board (FIFO)" do
@@ -121,26 +121,26 @@ describe WorkerRoulette do
121
121
  most_recent_sender = 'most_recent_sender'
122
122
  most_recent_foreman = WorkerRoulette.foreman(most_recent_sender)
123
123
  most_recent_foreman.enqueue_work_order(work_orders)
124
- redis.zrange(subject.job_board_key, 0, -1).should == [oldest_sender, most_recent_sender]
124
+ expect(redis.zrange(subject.job_board_key, 0, -1)).to eq([oldest_sender, most_recent_sender])
125
125
  subject.work_orders!
126
- redis.zrange(subject.job_board_key, 0, -1).should == [most_recent_sender]
126
+ expect(redis.zrange(subject.job_board_key, 0, -1)).to eq([most_recent_sender])
127
127
  end
128
128
 
129
129
  it "should get the work_orders from the next queue when a new job is ready" do
130
130
  subject.work_orders!
131
- subject.should_receive(:work_orders!).twice.and_call_original
131
+ expect(subject).to receive(:work_orders!).twice.and_call_original
132
132
 
133
133
  publisher = -> {foreman.enqueue_work_order(work_orders); subject.unsubscribe}
134
134
 
135
135
  subject.wait_for_work_orders(publisher) do |redis_work_orders|
136
- redis_work_orders.should == [work_orders_with_headers]
137
- subject.last_sender.should == nil
136
+ expect(redis_work_orders).to eq([work_orders_with_headers])
137
+ expect(subject.last_sender).to be_nil
138
138
  end
139
139
  end
140
140
 
141
141
  it "should publish and subscribe on custom channels" do
142
142
  tradesman = WorkerRoulette.tradesman('good_channel')
143
- tradesman.should_receive(:work_orders!).twice.and_call_original
143
+ expect(tradesman).to receive(:work_orders!).twice.and_call_original
144
144
 
145
145
  good_foreman = WorkerRoulette.foreman('foreman', 'good_channel')
146
146
  bad_foreman = WorkerRoulette.foreman('foreman', 'bad_channel')
@@ -153,9 +153,9 @@ describe WorkerRoulette do
153
153
  end
154
154
 
155
155
  tradesman.wait_for_work_orders(publish) do |work|
156
- work.to_s.should match("some old fashion work")
157
- work.to_s.should_not match("evil")
158
- tradesman.last_sender.should == nil
156
+ expect(work.to_s).to match("some old fashion work")
157
+ expect(work.to_s).not_to match("evil")
158
+ expect(tradesman.last_sender).to be_nil
159
159
  end
160
160
  end
161
161
 
@@ -169,7 +169,7 @@ describe WorkerRoulette do
169
169
  Thread.new {WorkerRoulette.tradesman_connection_pool.with {|pooled_redis| pooled_redis.get("foo")}}
170
170
  end.each(&:join)
171
171
  WorkerRoulette.tradesman_connection_pool.with do |pooled_redis|
172
- pooled_redis.info["connected_clients"].to_i.should > (WorkerRoulette.pool_size)
172
+ expect(pooled_redis.info["connected_clients"].to_i).to be > (WorkerRoulette.pool_size)
173
173
  end
174
174
  end
175
175
 
@@ -24,14 +24,14 @@ module WorkerRoulette
24
24
 
25
25
  it "should lock a queue when it reads from it" do
26
26
  evented_readlock_preconditions do
27
- redis.get(lock_key).should_not be_nil
27
+ expect(redis.get(lock_key)).not_to be_nil
28
28
  done
29
29
  end
30
30
  end
31
31
 
32
32
  it "should set the lock to expire in 1 second" do
33
33
  evented_readlock_preconditions do
34
- redis.ttl(lock_key).should == 1
34
+ expect(redis.ttl(lock_key)).to eq(1)
35
35
  done
36
36
  end
37
37
  end
@@ -39,7 +39,7 @@ module WorkerRoulette
39
39
  it "should not read a locked queue" do
40
40
  evented_readlock_preconditions do
41
41
  foreman.enqueue_work_order(work_orders) do #locked
42
- subject_two.work_orders! {|work |work.should == []; done}
42
+ subject_two.work_orders! { |work| expect(work).to be_empty; done}
43
43
  end
44
44
  end
45
45
  end
@@ -48,7 +48,7 @@ module WorkerRoulette
48
48
  evented_readlock_preconditions do
49
49
  foreman.enqueue_work_order(work_orders) do #locked
50
50
  number_two.enqueue_work_order(work_orders) do #unlocked
51
- subject_two.work_orders!{|work| work.first['headers']['sender'].should == 'number_two'; done}
51
+ subject_two.work_orders!{|work| expect(work.first['headers']['sender']).to eq('number_two'); done}
52
52
  end
53
53
  end
54
54
  end
@@ -57,10 +57,10 @@ module WorkerRoulette
57
57
  it "should release its last lock when it asks for its next work order from another sender" do
58
58
  evented_readlock_preconditions do
59
59
  number_two.enqueue_work_order(work_orders) do #unlocked
60
- subject.last_sender.should == sender
60
+ expect(subject.last_sender).to eq(sender)
61
61
  subject.work_orders! do |work|
62
- work.first['headers']['sender'].should == 'number_two'
63
- redis.get(lock_key).should == nil
62
+ expect(work.first['headers']['sender']).to eq('number_two')
63
+ expect(redis.get(lock_key)).to be_nil
64
64
  done
65
65
  end
66
66
  end
@@ -71,9 +71,9 @@ module WorkerRoulette
71
71
  evented_readlock_preconditions do
72
72
  foreman.enqueue_work_order(work_orders) do #locked
73
73
  subject.work_orders! do |work|
74
- work.should == [work_orders_with_headers]
75
- subject.last_sender.should == sender
76
- redis.get(lock_key).should_not == nil
74
+ expect(work).to eq([work_orders_with_headers])
75
+ expect(subject.last_sender).to eq(sender)
76
+ expect(redis.get(lock_key)).not_to be_nil
77
77
  done
78
78
  end
79
79
  end
@@ -83,11 +83,11 @@ module WorkerRoulette
83
83
  it "should not take out another lock if there is no work to do" do
84
84
  evented_readlock_preconditions do
85
85
  foreman.enqueue_work_order(work_orders) do #locked
86
- subject.work_orders! do |work|
87
- work.should == [work_orders_with_headers]
86
+ subject.work_orders! do |work_order|
87
+ expect(work_order).to eq([work_orders_with_headers])
88
88
  subject.work_orders! do |work|
89
- work.should == []
90
- redis.get(lock_key).should == nil
89
+ expect(work).to be_empty
90
+ expect(redis.get(lock_key)).to be_nil
91
91
  done
92
92
  end
93
93
  end
@@ -99,9 +99,9 @@ module WorkerRoulette
99
99
  def evented_readlock_preconditions(&spec_block)
100
100
  foreman.enqueue_work_order(work_orders) do
101
101
  subject.work_orders! do |work|
102
- work.should == [work_orders_with_headers]
102
+ expect(work).to eq([work_orders_with_headers])
103
103
  spec_block.call
104
104
  end
105
105
  end
106
106
  end
107
- end
107
+ end
@@ -17,22 +17,22 @@ module WorkerRoulette
17
17
  it "should load and call a lua script" do
18
18
  lua_script = 'return redis.call("SET", KEYS[1], ARGV[1])'
19
19
  Lua.call(lua_script, ['foo'], ['daddy']) do |result|
20
- Lua.cache.keys.first.should == lua_script
21
- Lua.cache.values.first.should == Digest::SHA1.hexdigest(lua_script)
22
- result.should == "OK"
20
+ expect(Lua.cache.keys.first).to eq(lua_script)
21
+ expect(Lua.cache.values.first).to eq(Digest::SHA1.hexdigest(lua_script))
22
+ expect(result).to eq("OK")
23
23
  done
24
24
  end
25
25
  end
26
26
 
27
27
  it "should send a sha instead of a script once the script has been cached" do
28
28
  lua_script = 'return KEYS'
29
- Lua.should_receive(:eval).and_call_original
29
+ expect(Lua).to receive(:eval).and_call_original
30
30
 
31
31
  Lua.call(lua_script) do |result|
32
+ expect(Lua).not_to receive(:eval)
32
33
 
33
- Lua.should_not_receive(:eval)
34
- Lua.call(lua_script) do |result|
35
- result.should == []
34
+ Lua.call(lua_script) do |inner_result|
35
+ expect(inner_result).to be_empty
36
36
  done
37
37
  end
38
38
  end
@@ -46,4 +46,4 @@ module WorkerRoulette
46
46
  done
47
47
  end
48
48
  end
49
- end
49
+ end
@@ -19,56 +19,54 @@ module WorkerRoulette
19
19
  redis.script(:flush)
20
20
  redis.flushdb
21
21
  foreman.enqueue_work_order(work_orders)
22
- subject.work_orders!.should == [work_orders_with_headers]
22
+ expect(subject.work_orders!).to eq([work_orders_with_headers])
23
23
  end
24
24
 
25
25
  it "should lock a queue when it reads from it" do
26
- redis.get(lock_key).should_not be_nil
26
+ expect(redis.get(lock_key)).not_to be_nil
27
27
  end
28
28
 
29
29
  it "should set the lock to expire in 1 second" do
30
- redis.ttl(lock_key).should == 1
30
+ expect(redis.ttl(lock_key)).to eq(1)
31
31
  end
32
32
 
33
33
  it "should not read a locked queue" do
34
34
  foreman.enqueue_work_order(work_orders) #locked
35
- subject_two.work_orders!.should == []
35
+ expect(subject_two.work_orders!).to be_empty
36
36
  end
37
37
 
38
38
  it "should read from the first available queue that is not locked" do
39
39
  foreman.enqueue_work_order(work_orders) #locked
40
40
  number_two.enqueue_work_order(work_orders) #unlocked
41
- subject_two.work_orders!.first['headers']['sender'].should == 'number_two'
41
+ expect(subject_two.work_orders!.first['headers']['sender']).to eq('number_two')
42
42
  end
43
43
 
44
44
  it "should release its previous lock when it asks for work from another sender" do
45
45
  number_two.enqueue_work_order(work_orders) #unlocked
46
- subject.last_sender.should == sender
47
- subject.work_orders!.first['headers']['sender'].should == 'number_two'
48
- redis.get(lock_key).should == nil
46
+ expect(subject.last_sender).to eq(sender)
47
+ expect(subject.work_orders!.first['headers']['sender']).to eq('number_two')
48
+ expect(redis.get(lock_key)).to be_nil
49
49
  end
50
50
 
51
51
  it "should not release its lock when it asks for work from the same sender" do
52
52
  foreman.enqueue_work_order(work_orders) #locked
53
- subject.work_orders!.should == [work_orders_with_headers]
54
- subject.last_sender.should == sender
53
+ expect(subject.work_orders!).to eq([work_orders_with_headers])
54
+ expect(subject.last_sender).to eq(sender)
55
55
 
56
56
  foreman.enqueue_work_order(work_orders) #locked
57
- subject.work_orders!.should == [work_orders_with_headers]
58
- subject.last_sender.should == sender
57
+ expect(subject.work_orders!).to eq([work_orders_with_headers])
58
+ expect(subject.last_sender).to eq(sender)
59
59
 
60
- redis.get(lock_key).should_not == nil
60
+ expect(redis.get(lock_key)).not_to be_nil
61
61
  end
62
62
 
63
63
  it "should release its previous lock if there is no work to do from the same sender" do
64
64
  foreman.enqueue_work_order(work_orders) #locked
65
- subject.work_orders!.should == [work_orders_with_headers]
66
- subject.work_orders!.should == []
67
- redis.get(lock_key).should == nil
65
+ expect(subject.work_orders!).to eq([work_orders_with_headers])
66
+ expect(subject.work_orders!).to be_empty
67
+ expect(redis.get(lock_key)).to be_nil
68
68
  end
69
69
 
70
- xit "pubsub should clean up one contention orremove the lock on the same sender queue automaticly" do
71
-
72
- end
70
+ pending "pubsub should clean up one contention or remove the lock on the same sender queue automaticly"
73
71
  end
74
- end
72
+ end
@@ -4,18 +4,18 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'worker_roulette/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "worker_roulette"
7
+ spec.name = 'worker_roulette'
8
8
  spec.version = WorkerRoulette::VERSION
9
- spec.authors = ["Paul Saieg"]
10
- spec.email = ["classicist@gmail.com"]
11
- spec.description = %q{Write a gem description}
12
- spec.summary = %q{Write a gem summary}
13
- spec.homepage = "https://github.com/nexiahome/worker_roulette"
9
+ spec.authors = ['Paul Saieg']
10
+ spec.email = ['classicist@gmail.com']
11
+ spec.description = %q{Pub Sub Queue for Redis that ensures ordered processing}
12
+ spec.summary = %q{Pub Sub Queue for Redis that ensures ordered processing}
13
+ spec.homepage = 'https://github.com/nexiahome/worker_roulette'
14
14
 
15
15
  spec.files = `git ls-files`.split($/)
16
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
17
  spec.test_files = spec.files.grep(%r{^(spec)/})
18
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
19
19
 
20
20
  spec.add_dependency 'oj'
21
21
  spec.add_dependency 'redis', '~> 3.0.7'
@@ -24,14 +24,13 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'connection_pool'
25
25
  spec.add_dependency 'eventmachine', '~> 1.0.3'
26
26
 
27
- spec.add_development_dependency "bundler"
28
- spec.add_development_dependency "rake"
29
- spec.add_development_dependency 'rspec'
27
+ spec.add_development_dependency 'bundler'
28
+ spec.add_development_dependency 'rake'
29
+ spec.add_development_dependency 'rspec', '~> 3.0.0'
30
30
  spec.add_development_dependency 'pry-debugger'
31
31
  spec.add_development_dependency 'simplecov'
32
32
  spec.add_development_dependency 'simplecov-rcov'
33
33
  spec.add_development_dependency 'rspec_junit_formatter'
34
- spec.add_development_dependency 'evented-spec'
35
34
  spec.add_development_dependency 'guard'
36
35
  spec.add_development_dependency 'guard-rspec'
37
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: worker_roulette
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Saieg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-13 00:00:00.000000000 Z
11
+ date: 2014-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -126,16 +126,16 @@ dependencies:
126
126
  name: rspec
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ! '>='
129
+ - - ~>
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: 3.0.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ! '>='
136
+ - - ~>
137
137
  - !ruby/object:Gem::Version
138
- version: '0'
138
+ version: 3.0.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: pry-debugger
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -192,20 +192,6 @@ dependencies:
192
192
  - - ! '>='
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
- - !ruby/object:Gem::Dependency
196
- name: evented-spec
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - ! '>='
200
- - !ruby/object:Gem::Version
201
- version: '0'
202
- type: :development
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - ! '>='
207
- - !ruby/object:Gem::Version
208
- version: '0'
209
195
  - !ruby/object:Gem::Dependency
210
196
  name: guard
211
197
  requirement: !ruby/object:Gem::Requirement
@@ -234,7 +220,7 @@ dependencies:
234
220
  - - ! '>='
235
221
  - !ruby/object:Gem::Version
236
222
  version: '0'
237
- description: Write a gem description
223
+ description: Pub Sub Queue for Redis that ensures ordered processing
238
224
  email:
239
225
  - classicist@gmail.com
240
226
  executables: []
@@ -287,7 +273,7 @@ rubyforge_project:
287
273
  rubygems_version: 2.2.2
288
274
  signing_key:
289
275
  specification_version: 4
290
- summary: Write a gem summary
276
+ summary: Pub Sub Queue for Redis that ensures ordered processing
291
277
  test_files:
292
278
  - spec/benchmark/perf_test.rb
293
279
  - spec/helpers/.gitkeep