em-jack 0.1.3 → 0.1.4
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.
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/Rakefile +11 -0
- data/bin/shell +130 -0
- data/em-jack.gemspec +27 -0
- data/lib/em-jack.rb +1 -3
- data/lib/em-jack/connection.rb +59 -22
- data/lib/em-jack/version.rb +3 -0
- data/spec/em-jack/connection_spec.rb +589 -0
- data/spec/em-jack/fiber_spec.rb +56 -0
- data/spec/em-jack/job_spec.rb +48 -0
- data/spec/spec_helper.rb +6 -0
- metadata +90 -70
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Rakefile
ADDED
data/bin/shell
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift("lib")
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'eventmachine'
|
7
|
+
require 'em-jack'
|
8
|
+
require 'pp'
|
9
|
+
|
10
|
+
$stdout.sync = true
|
11
|
+
|
12
|
+
class KeyboardHandler < EM::Connection
|
13
|
+
include EM::Protocols::LineText2
|
14
|
+
|
15
|
+
def post_init
|
16
|
+
@jack = EMJack::Connection.new
|
17
|
+
@jack.on_error { |err| puts "ERROR: #{err}" }
|
18
|
+
|
19
|
+
print "> "
|
20
|
+
end
|
21
|
+
|
22
|
+
def receive_line(line)
|
23
|
+
line.chomp!
|
24
|
+
line.gsub!(/^\s+/, '')
|
25
|
+
|
26
|
+
df = case(line)
|
27
|
+
when /^\s*$/ then
|
28
|
+
# noop
|
29
|
+
nil
|
30
|
+
|
31
|
+
when /^use / then
|
32
|
+
tube = line.gsub(/use /, '')
|
33
|
+
@jack.use(tube) { |tube| puts "Using #{tube}" }
|
34
|
+
|
35
|
+
when /^watch / then
|
36
|
+
tube = line.gsub(/watch /, '')
|
37
|
+
@jack.watch(tube) { |tube| puts "Watching #{tube}" }
|
38
|
+
|
39
|
+
when /^ignore / then
|
40
|
+
tube = line.gsub(/ignore /, '')
|
41
|
+
@jack.ignore(tube) { |tube| puts "Ignoring #{tube}" }
|
42
|
+
|
43
|
+
when /^put / then
|
44
|
+
msg = line.gsub(/put /, '')
|
45
|
+
@jack.put(msg) { |id| puts "Inserted job #{id}" }
|
46
|
+
|
47
|
+
when /^delete / then
|
48
|
+
id = line.gsub(/delete /, '').to_i
|
49
|
+
job = EMJack::Job.new(@jack, id, "asdf")
|
50
|
+
job.delete { puts "Deleted" }
|
51
|
+
|
52
|
+
when 'reserve' then
|
53
|
+
@jack.reserve { |job| puts "Reserved #{job}" }
|
54
|
+
|
55
|
+
when 'list-tubes' then
|
56
|
+
@jack.list { |tubes| pp tubes }
|
57
|
+
|
58
|
+
when 'list-watched' then
|
59
|
+
@jack.list(:watched) { |tubes| pp tubes }
|
60
|
+
|
61
|
+
when 'list-used' then
|
62
|
+
@jack.list(:used) { |tube| puts "Using #{tube}" }
|
63
|
+
|
64
|
+
when /^peek\s+(\d+)\s*$/ then
|
65
|
+
@jack.peek($1) { |job| puts "Peeked: #{job}" }
|
66
|
+
|
67
|
+
when 'peek-ready' then
|
68
|
+
@jack.peek(:ready) { |job| puts "Peeked ready: #{job}"}
|
69
|
+
|
70
|
+
when 'peek-delayed' then
|
71
|
+
@jack.peek(:delayed) { |job| puts "Peeked delayed: #{job}" }
|
72
|
+
|
73
|
+
when 'peek-buried' then
|
74
|
+
@jack.peek(:buried) { |job| puts "Peeked buried: #{job}" }
|
75
|
+
|
76
|
+
when 'stats' then
|
77
|
+
@jack.stats { |stats| pp stats }
|
78
|
+
|
79
|
+
when /^stats-tube\s+(.*)$/ then
|
80
|
+
@jack.stats(:tube, $1) { |stats| pp stats }
|
81
|
+
|
82
|
+
when /^stats-job\s+(\d+)/ then
|
83
|
+
j = EMJack::Job.new(@jack, $1, "blah")
|
84
|
+
j.stats { |stats| pp stats }
|
85
|
+
|
86
|
+
when 'help' then
|
87
|
+
msg = "COMMANDS:\n"
|
88
|
+
msg << " put <msg> - put message onto beanstalk\n"
|
89
|
+
msg << " reserve - reserve a job on beanstalk\n"
|
90
|
+
msg << " delete <id> - delete message with ID <id>\n"
|
91
|
+
msg << "\n"
|
92
|
+
msg << " use <tube> - use tube for messages\n"
|
93
|
+
msg << " watch <tube> - add <tube to watch list for messages\n"
|
94
|
+
msg << "\n"
|
95
|
+
msg << " stats - display beanstalk stats\n"
|
96
|
+
msg << " stats-tube <tube> - display tube stats\n"
|
97
|
+
msg << " stats-job <id> - display job stats\n"
|
98
|
+
msg << "\n"
|
99
|
+
msg << " list-tubes - display beanstalk tubes\n"
|
100
|
+
msg << " list-used - display the currently used tube\n"
|
101
|
+
msg << " list-watched - display the currently watched tubes\n"
|
102
|
+
msg << "\n"
|
103
|
+
msg << " peek <id> - peek at job with ID <id>\n"
|
104
|
+
msg << " peek-ready - peek at the first job in the ready queue\n"
|
105
|
+
msg << " peek-delayed - peek at the delayed job with shortest delay\n"
|
106
|
+
msg << " peek-buried - peek at the next buried job\n"
|
107
|
+
msg << "\n"
|
108
|
+
msg << " help - this help text\n"
|
109
|
+
msg << " quit - quit application\n"
|
110
|
+
|
111
|
+
puts msg
|
112
|
+
nil
|
113
|
+
|
114
|
+
when 'quit' then
|
115
|
+
EM.stop_event_loop
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
|
119
|
+
unless df.nil?
|
120
|
+
df.callback { print "> " }
|
121
|
+
df.errback { print "> " }
|
122
|
+
end
|
123
|
+
|
124
|
+
print "> "
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
EM.run do
|
129
|
+
EM.open_keyboard(KeyboardHandler)
|
130
|
+
end
|
data/em-jack.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$:.unshift(lib) unless $:.include?(lib)
|
4
|
+
|
5
|
+
require 'em-jack/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'em-jack'
|
9
|
+
s.version = EMJack::VERSION
|
10
|
+
s.authors = ['Dan Sinclair']
|
11
|
+
s.email = ['dj2@everburning.com']
|
12
|
+
s.homepage = 'https://github.com/dj2/em-jack/'
|
13
|
+
s.summary = 'An evented Beanstalk client'
|
14
|
+
s.description = 'An evented Beanstalk client'
|
15
|
+
|
16
|
+
s.required_rubygems_version = '>= 1.3.6'
|
17
|
+
|
18
|
+
s.add_dependency 'eventmachine', ['>= 0.12.10']
|
19
|
+
|
20
|
+
s.add_development_dependency 'bundler', ['~> 1.0.13']
|
21
|
+
s.add_development_dependency 'rake', ['>= 0.8.7']
|
22
|
+
s.add_development_dependency 'rspec', ['~> 2.6']
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
26
|
+
s.require_path = ['lib']
|
27
|
+
end
|
data/lib/em-jack.rb
CHANGED
@@ -4,13 +4,11 @@ require 'em-jack/job'
|
|
4
4
|
require 'em-jack/errors'
|
5
5
|
require 'em-jack/beanstalk_connection'
|
6
6
|
require 'em-jack/connection'
|
7
|
+
require 'em-jack/version'
|
7
8
|
|
8
9
|
Dir["#{File.dirname(__FILE__)}/em-jack/handlers/*.rb"].each do |file|
|
9
10
|
require file
|
10
11
|
end
|
11
12
|
|
12
13
|
module EMJack
|
13
|
-
module VERSION
|
14
|
-
STRING = '0.1.3'
|
15
|
-
end
|
16
14
|
end
|
data/lib/em-jack/connection.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'eventmachine'
|
2
2
|
require 'yaml'
|
3
|
+
require 'uri'
|
3
4
|
|
4
5
|
module EMJack
|
5
6
|
class Connection
|
@@ -21,15 +22,24 @@ module EMJack
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def initialize(opts = {})
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
case opts
|
26
|
+
when Hash
|
27
|
+
@host = opts[:host] || 'localhost'
|
28
|
+
@port = opts[:port] || 11300
|
29
|
+
@tube = opts[:tube]
|
30
|
+
when String
|
31
|
+
uri = URI.parse(opts)
|
32
|
+
@host = uri.host || 'localhost'
|
33
|
+
@port = uri.port || 11300
|
34
|
+
@tube = uri.path.gsub(/^\//, '') # Kill the leading /
|
35
|
+
end
|
27
36
|
|
28
37
|
reset_tube_state
|
29
38
|
|
30
39
|
@data = ""
|
31
40
|
@retries = 0
|
32
41
|
@in_reserve = false
|
42
|
+
@fiberized = false
|
33
43
|
|
34
44
|
@conn = EM::connect(host, port, EMJack::BeanstalkConnection) do |conn|
|
35
45
|
conn.client = self
|
@@ -42,7 +52,7 @@ module EMJack
|
|
42
52
|
end
|
43
53
|
|
44
54
|
def reset_tube_state
|
45
|
-
prev_used = @used_tube
|
55
|
+
prev_used = @used_tube
|
46
56
|
prev_watched = @watched_tubes.dup if @watched_tubes
|
47
57
|
|
48
58
|
@used_tube = 'default'
|
@@ -53,16 +63,15 @@ module EMJack
|
|
53
63
|
end
|
54
64
|
|
55
65
|
def fiber!
|
56
|
-
|
57
|
-
|
58
|
-
end)
|
66
|
+
@fiberized = true
|
67
|
+
|
68
|
+
eigen = (class << self; self; end)
|
59
69
|
eigen.instance_eval do
|
60
70
|
%w(use reserve ignore watch peek stats list delete touch bury kick pause release put).each do |meth|
|
61
71
|
alias_method :"a#{meth}", meth.to_sym
|
62
72
|
define_method(meth.to_sym) do |*args|
|
63
73
|
fib = Fiber.current
|
64
74
|
ameth = :"a#{meth}"
|
65
|
-
p [ameth, *args]
|
66
75
|
proc = lambda { |*result| fib.resume(*result) }
|
67
76
|
send(ameth, *args, &proc)
|
68
77
|
Fiber.yield
|
@@ -219,16 +228,26 @@ module EMJack
|
|
219
228
|
end
|
220
229
|
|
221
230
|
def each_job(timeout = nil, &blk)
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
231
|
+
if (@fiberized)
|
232
|
+
work = Proc.new do
|
233
|
+
Fiber.new do
|
234
|
+
job = reserve(timeout)
|
235
|
+
blk.call(job)
|
236
|
+
end.resume
|
237
|
+
EM.next_tick { work.call }
|
227
238
|
end
|
228
|
-
|
229
|
-
|
239
|
+
else
|
240
|
+
work = Proc.new do
|
241
|
+
r = reserve(timeout)
|
242
|
+
r.callback do |job|
|
243
|
+
blk.call(job)
|
244
|
+
EM.next_tick { work.call }
|
245
|
+
end
|
246
|
+
r.errback do
|
247
|
+
EM.next_tick { work.call }
|
248
|
+
end
|
230
249
|
end
|
231
|
-
end
|
250
|
+
end
|
232
251
|
work.call
|
233
252
|
end
|
234
253
|
|
@@ -236,9 +255,12 @@ module EMJack
|
|
236
255
|
@reconnect_proc = nil
|
237
256
|
@retries = 0
|
238
257
|
succeed
|
258
|
+
@connected = true
|
259
|
+
@connected_callback.call if @connected_callback
|
239
260
|
end
|
240
261
|
|
241
262
|
def disconnected
|
263
|
+
@connected = false
|
242
264
|
d = @deferrables.dup
|
243
265
|
|
244
266
|
## if reconnecting, need to fail ourself to remove any callbacks
|
@@ -256,18 +278,26 @@ module EMJack
|
|
256
278
|
end
|
257
279
|
|
258
280
|
prev_used, prev_watched = reset_tube_state
|
259
|
-
|
281
|
+
unless @reconnect_proc
|
282
|
+
recon = Proc.new { reconnect(prev_used, prev_watched) }
|
283
|
+
if @fiberized
|
284
|
+
@reconnect_proc = Proc.new { Fiber.new { recon.call }.resume }
|
285
|
+
else
|
286
|
+
@reconnect_proc = recon
|
287
|
+
end
|
288
|
+
end
|
260
289
|
|
261
290
|
@retries += 1
|
262
291
|
EM.add_timer(5) { @reconnect_proc.call }
|
263
292
|
end
|
264
|
-
|
293
|
+
|
265
294
|
def reconnect(prev_used, prev_watched)
|
266
295
|
@conn.reconnect(@host, @port)
|
267
296
|
|
268
297
|
use(prev_used) if prev_used
|
269
|
-
|
270
|
-
|
298
|
+
|
299
|
+
[prev_watched].flatten.compact.each do |tube|
|
300
|
+
@fiberized ? awatch(tube) : watch(tube)
|
271
301
|
end
|
272
302
|
end
|
273
303
|
|
@@ -275,7 +305,6 @@ module EMJack
|
|
275
305
|
@retries = 0
|
276
306
|
|
277
307
|
prev_used, prev_watched = reset_tube_state
|
278
|
-
|
279
308
|
EM.next_tick { reconnect(prev_used, prev_watched) }
|
280
309
|
end
|
281
310
|
|
@@ -294,11 +323,19 @@ module EMJack
|
|
294
323
|
def on_error(&blk)
|
295
324
|
@error_callback = blk
|
296
325
|
end
|
297
|
-
|
326
|
+
|
298
327
|
def on_disconnect(&blk)
|
299
328
|
@disconnected_callback = blk
|
300
329
|
end
|
301
330
|
|
331
|
+
def on_connect(&blk)
|
332
|
+
@connected_callback = blk
|
333
|
+
end
|
334
|
+
|
335
|
+
def connected?
|
336
|
+
@connected
|
337
|
+
end
|
338
|
+
|
302
339
|
def received(data)
|
303
340
|
@data << data
|
304
341
|
|
@@ -0,0 +1,589 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EMJack::Connection do
|
4
|
+
let(:conn) do
|
5
|
+
conn = EMJack::Connection.new
|
6
|
+
conn.connected
|
7
|
+
conn
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:connection_mock) do
|
11
|
+
connection_mock = mock(:conn)
|
12
|
+
connection_mock
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
EM.stub!(:connect).and_return(connection_mock)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "uri connection string" do
|
20
|
+
let(:conn) do
|
21
|
+
EMJack::Connection.new('beanstalk://leet:1337/leetube')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should parse host" do
|
25
|
+
conn.host.should eql('leet')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should parse tube" do
|
29
|
+
connection_mock.should_receive(:send).once.with(:use, "leetube")
|
30
|
+
connection_mock.should_receive(:send).once.with(:watch, "leetube")
|
31
|
+
conn.connected
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should parse port" do
|
35
|
+
conn.port.should eql(1337)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'defaults' do
|
40
|
+
it 'host of "localhost"' do
|
41
|
+
conn.host.should == 'localhost'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'port of 11300' do
|
45
|
+
conn.port.should == 11300
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'watch and use to provided tube on connect' do
|
49
|
+
connection_mock.should_receive(:send).once.with(:use, "mytube")
|
50
|
+
connection_mock.should_receive(:send).once.with(:watch, "mytube")
|
51
|
+
conn = EMJack::Connection.new(:tube => "mytube")
|
52
|
+
conn.connected
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'sending commands' do
|
58
|
+
it "doesn't send the command until we've connected" do
|
59
|
+
conn = EMJack::Connection.new
|
60
|
+
conn.should_not_receive(:send)
|
61
|
+
conn.use("mytube")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "sends commands after we've connected" do
|
65
|
+
connected = false
|
66
|
+
|
67
|
+
connection_mock.should_receive(:send).twice do
|
68
|
+
connected.should be_true
|
69
|
+
end
|
70
|
+
|
71
|
+
conn = EMJack::Connection.new
|
72
|
+
conn.use('mytube')
|
73
|
+
conn.watch('mytube')
|
74
|
+
|
75
|
+
connected = true
|
76
|
+
conn.connected
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'the "use" command' do
|
80
|
+
connection_mock.should_receive(:send).once.with(:use, "mytube")
|
81
|
+
conn.use("mytube")
|
82
|
+
end
|
83
|
+
|
84
|
+
it "doesn't send the use command to the currently used tube" do
|
85
|
+
connection_mock.should_receive(:send).once.with(:use, "mytube")
|
86
|
+
conn.use("mytube")
|
87
|
+
conn.use("mytube")
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'the "watch" command' do
|
91
|
+
connection_mock.should_receive(:send).once.with(:watch, "mytube")
|
92
|
+
conn.watch("mytube")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "doesn't send the watch command for a tube currently watched" do
|
96
|
+
connection_mock.should_not_receive(:send)
|
97
|
+
conn.instance_variable_get("@watched_tubes").push("mytube")
|
98
|
+
conn.watch("mytube")
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "'put' command" do
|
102
|
+
it 'basic' do
|
103
|
+
msg = "my message"
|
104
|
+
connection_mock.should_receive(:send_with_data).once.
|
105
|
+
with(:put, msg, anything, anything, anything, msg.length)
|
106
|
+
conn.put(msg)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'defaults the delay, priority and ttr settings' do
|
110
|
+
connection_mock.should_receive(:send_with_data).once.
|
111
|
+
with(:put, anything, 65536, 0, 300, anything)
|
112
|
+
conn.put("msg")
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'accepts a delay setting' do
|
116
|
+
connection_mock.should_receive(:send_with_data).once.
|
117
|
+
with(:put, anything, anything, 42, anything, anything)
|
118
|
+
conn.put("msg", :delay => 42)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'accepts a ttr setting' do
|
122
|
+
connection_mock.should_receive(:send_with_data).once.
|
123
|
+
with(:put, anything, anything, anything, 999, anything)
|
124
|
+
conn.put("msg", :ttr => 999)
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'accepts a priority setting' do
|
128
|
+
connection_mock.should_receive(:send_with_data).once.
|
129
|
+
with(:put, anything, 233, anything, anything, anything)
|
130
|
+
conn.put("msg", :priority => 233)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'accepts a priority, delay and ttr setting' do
|
134
|
+
connection_mock.should_receive(:send_with_data).once.
|
135
|
+
with(:put, anything, 99, 42, 2000, anything)
|
136
|
+
conn.put("msg", :priority => 99, :delay => 42, :ttr => 2000)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'forces delay to be >= 0' do
|
140
|
+
connection_mock.should_receive(:send_with_data).once.
|
141
|
+
with(:put, anything, anything, 0, anything, anything)
|
142
|
+
conn.put("msg", :delay => -42)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'forces ttr to be >= 0' do
|
146
|
+
connection_mock.should_receive(:send_with_data).once.
|
147
|
+
with(:put, anything, anything, anything, 300, anything)
|
148
|
+
conn.put("msg", :ttr => -42)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'forces priority to be >= 0' do
|
152
|
+
connection_mock.should_receive(:send_with_data).once.
|
153
|
+
with(:put, anything, 65536, anything, anything, anything)
|
154
|
+
conn.put("msg", :priority => -42)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'forces priority to be < 2**32' do
|
158
|
+
connection_mock.should_receive(:send_with_data).once.
|
159
|
+
with(:put, anything, (2 ** 32), anything, anything, anything)
|
160
|
+
conn.put("msg", :priority => (2 ** 32 + 1))
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'handles a non-string provided as the put message' do
|
164
|
+
msg = 22
|
165
|
+
connection_mock.should_receive(:send_with_data).once.
|
166
|
+
with(:put, msg.to_s, anything, anything, anything, msg.to_s.length)
|
167
|
+
conn.put(msg)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'the "delete" command' do
|
172
|
+
connection_mock.should_receive(:send).once.with(:delete, 1)
|
173
|
+
job = EMJack::Job.new(nil, 1, "body")
|
174
|
+
conn.delete(job)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'the "touch" command' do
|
178
|
+
connection_mock.should_receive(:send).once.with(:touch, 1)
|
179
|
+
job = EMJack::Job.new(nil, 1, "body")
|
180
|
+
conn.touch(job)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'the "kick" command' do
|
184
|
+
connection_mock.should_receive(:send).once.with(:kick, 15)
|
185
|
+
conn.kick(15)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'the "kick" command defaults to 1' do
|
189
|
+
connection_mock.should_receive(:send).once.with(:kick, 1)
|
190
|
+
conn.kick
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'the "pause-tube" command' do
|
194
|
+
connection_mock.should_receive(:send).once.with(:'pause-tube', 60)
|
195
|
+
conn.pause('mytube', 60)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'the "bury" command' do
|
199
|
+
connection_mock.should_receive(:send).once.with(:'bury', 1, 1234)
|
200
|
+
job = EMJack::Job.new(nil, 1, "body")
|
201
|
+
conn.bury(job, 1234)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'handles a nil job sent to the "delete" command' do
|
205
|
+
connection_mock.should_not_receive(:send).with(:delete, nil)
|
206
|
+
conn.delete(nil)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'the "reserve" command' do
|
210
|
+
connection_mock.should_receive(:send).with(:reserve)
|
211
|
+
conn.reserve
|
212
|
+
end
|
213
|
+
|
214
|
+
describe 'stats' do
|
215
|
+
it 'default' do
|
216
|
+
connection_mock.should_receive(:send).once.with(:stats)
|
217
|
+
conn.stats
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'job' do
|
221
|
+
job = EMJack::Job.new(nil, 42, "blah")
|
222
|
+
|
223
|
+
connection_mock.should_receive(:send).once.with(:'stats-job', 42)
|
224
|
+
conn.stats(:job, job)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'tube' do
|
228
|
+
connection_mock.should_receive(:send).once.with(:'stats-tube', "mytube")
|
229
|
+
conn.stats(:tube, "mytube")
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'throws exception on invalid param' do
|
233
|
+
connection_mock.should_not_receive(:send)
|
234
|
+
lambda { conn.stats(:blah) }.should raise_error(EMJack::InvalidCommand)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe 'list' do
|
239
|
+
it 'default' do
|
240
|
+
connection_mock.should_receive(:send).once.with(:'list-tubes')
|
241
|
+
conn.list
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'tube used' do
|
245
|
+
connection_mock.should_receive(:send).once.with(:'list-tube-used')
|
246
|
+
conn.list(:used)
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'tubes watched' do
|
250
|
+
connection_mock.should_receive(:send).once.with(:'list-tubes-watched')
|
251
|
+
conn.list(:watched)
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'throws exception on invalid param' do
|
255
|
+
connection_mock.should_not_receive(:send)
|
256
|
+
lambda { conn.list(:blah) }.should raise_error(EMJack::InvalidCommand)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe 'peek' do
|
261
|
+
it 'with a job id' do
|
262
|
+
connection_mock.should_receive(:send).once.with(:'peek', 42)
|
263
|
+
conn.peek(42)
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'ready' do
|
267
|
+
connection_mock.should_receive(:send).once.with(:'peek-ready')
|
268
|
+
conn.peek(:ready)
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'delayed' do
|
272
|
+
connection_mock.should_receive(:send).once.with(:'peek-delayed')
|
273
|
+
conn.peek(:delayed)
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'buried' do
|
277
|
+
connection_mock.should_receive(:send).once.with(:'peek-buried')
|
278
|
+
conn.peek(:buried)
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'throws exception on invalid param' do
|
282
|
+
connection_mock.should_not_receive(:send)
|
283
|
+
lambda { conn.peek(:blah) }.should raise_error(EMJack::InvalidCommand)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
describe 'reconnect' do
|
289
|
+
let (:blk) do
|
290
|
+
Proc.new { "my proc" }
|
291
|
+
end
|
292
|
+
|
293
|
+
context 'on disconnect' do
|
294
|
+
before(:each) do
|
295
|
+
EM.should_receive(:add_timer).exactly(1).times.and_yield
|
296
|
+
connection_mock.as_null_object
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'reuses a used tube' do
|
300
|
+
conn.should_receive(:use).with('used')
|
301
|
+
conn.instance_variable_set(:@used_tube, 'used')
|
302
|
+
conn.disconnected
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'reuses a used tube' do
|
306
|
+
conn.should_receive(:use).with('default')
|
307
|
+
conn.disconnected
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'rewatches a watched tube' do
|
311
|
+
conn.should_receive(:watch).with('watched')
|
312
|
+
conn.instance_variable_set(:@watched_tubes, ['watched'])
|
313
|
+
conn.disconnected
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'rewatches multiple watched tubes' do
|
317
|
+
tubes = ['watched0', 'watched1']
|
318
|
+
|
319
|
+
conn.should_receive(:watch).twice do |tube|
|
320
|
+
tubes.delete(tube).should be_true
|
321
|
+
end
|
322
|
+
|
323
|
+
conn.instance_variable_set(:@watched_tubes, tubes)
|
324
|
+
conn.disconnected
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'rewatches and reuses previous tubes on disconnect' do
|
328
|
+
conn.should_receive(:use).with('used')
|
329
|
+
conn.should_receive(:watch).with('watched')
|
330
|
+
|
331
|
+
conn.instance_variable_set(:@used_tube, 'used')
|
332
|
+
conn.instance_variable_set(:@watched_tubes, ['watched'])
|
333
|
+
conn.disconnected
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'watches and uses previous tubes on disconnect' do
|
338
|
+
conn.should_receive(:watch).with('other')
|
339
|
+
connection_mock.as_null_object
|
340
|
+
|
341
|
+
EM.should_receive(:add_timer).exactly(1).times.and_yield
|
342
|
+
conn.instance_variable_set(:@watched_tubes, ['other'])
|
343
|
+
conn.disconnected
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'raises exception if it fails more then RETRY_COUNT times' do
|
347
|
+
EM.should_receive(:add_timer).exactly(5).times
|
348
|
+
|
349
|
+
5.times { conn.disconnected }
|
350
|
+
lambda { conn.disconnected }.should raise_error(EMJack::Disconnected)
|
351
|
+
end
|
352
|
+
|
353
|
+
it 'resets the retry count on connection' do
|
354
|
+
EM.should_receive(:add_timer).at_least(1).times
|
355
|
+
|
356
|
+
5.times { conn.disconnected }
|
357
|
+
conn.connected
|
358
|
+
lambda { conn.disconnected }.should_not raise_error(EMJack::Disconnected)
|
359
|
+
end
|
360
|
+
|
361
|
+
it 'handles deferrables added during the fail phase' do
|
362
|
+
EM.stub!(:add_timer)
|
363
|
+
|
364
|
+
count = 0
|
365
|
+
blk = Proc.new do
|
366
|
+
count += 1
|
367
|
+
if count < 2
|
368
|
+
df = conn.add_deferrable
|
369
|
+
df.errback { blk.call }
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
df = conn.add_deferrable
|
374
|
+
df.errback { blk.call }
|
375
|
+
|
376
|
+
conn.disconnected
|
377
|
+
count.should == 1
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
describe 'beanstalk responses' do
|
382
|
+
let(:df) do
|
383
|
+
conn.add_deferrable
|
384
|
+
end
|
385
|
+
|
386
|
+
%w(OUT_OF_MEMORY INTERNAL_ERROR DRAINING BAD_FORMAT
|
387
|
+
UNKNOWN_COMMAND EXPECTED_CRLF JOB_TOO_BIG DEADLINE_SOON
|
388
|
+
TIMED_OUT NOT_FOUND).each do |cmd|
|
389
|
+
it "#{cmd} messages" do
|
390
|
+
df.should_receive(:fail).with(cmd.downcase.to_sym)
|
391
|
+
conn.received("#{cmd}\r\n")
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
['buried', 'paused', 'touched', 'deleted'].each do |type|
|
396
|
+
it "#{type} messages" do
|
397
|
+
df.should_receive(:succeed)
|
398
|
+
conn.received("#{type.upcase}\r\n")
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
it 'inserted messages' do
|
403
|
+
df.should_receive(:succeed).with(40)
|
404
|
+
conn.received("INSERTED 40\r\n")
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'buried messages' do
|
408
|
+
df.should_receive(:fail).with(:buried, 40)
|
409
|
+
conn.received("BURIED 40\r\n")
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'kicked messages' do
|
413
|
+
df.should_receive(:succeed).with(15)
|
414
|
+
conn.received("KICKED 15\r\n")
|
415
|
+
end
|
416
|
+
|
417
|
+
it 'using messages' do
|
418
|
+
df.should_receive(:succeed).with("mytube")
|
419
|
+
conn.received("USING mytube\r\n")
|
420
|
+
end
|
421
|
+
|
422
|
+
it 'watching messages' do
|
423
|
+
df.should_receive(:succeed).with(24)
|
424
|
+
conn.received("WATCHING 24\r\n")
|
425
|
+
end
|
426
|
+
|
427
|
+
['reserved', 'found'].each do |type|
|
428
|
+
it "#{type} messages" do
|
429
|
+
msg = "This is my message"
|
430
|
+
|
431
|
+
df.should_receive(:succeed).with do |job|
|
432
|
+
job.class.should == EMJack::Job
|
433
|
+
job.jobid.should == 42
|
434
|
+
job.body.should == msg
|
435
|
+
end
|
436
|
+
|
437
|
+
conn.received("#{type.upcase} 42 #{msg.length}\r\n#{msg}\r\n")
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
it 'OK messages' do
|
442
|
+
msg =<<-HERE
|
443
|
+
---
|
444
|
+
current-jobs-urgent: 42
|
445
|
+
current-jobs-ready: 92
|
446
|
+
current-jobs-reserved: 18
|
447
|
+
current-jobs-delayed: 7
|
448
|
+
current-jobs-buried: 0
|
449
|
+
pid: 416
|
450
|
+
version: dev
|
451
|
+
HERE
|
452
|
+
|
453
|
+
df.should_receive(:succeed).with do |stats|
|
454
|
+
stats['current-jobs-urgent'].should == 42
|
455
|
+
stats['current-jobs-ready'].should == 92
|
456
|
+
stats['current-jobs-reserved'].should == 18
|
457
|
+
stats['current-jobs-delayed'].should == 7
|
458
|
+
stats['current-jobs-buried'].should == 0
|
459
|
+
stats['pid'].should == 416
|
460
|
+
stats['version'].should == 'dev'
|
461
|
+
end
|
462
|
+
|
463
|
+
conn.received("OK #{msg.length}\r\n#{msg}\r\n")
|
464
|
+
end
|
465
|
+
|
466
|
+
it 'receiving multiple replies in one packet' do
|
467
|
+
df.should_receive(:succeed).with(24)
|
468
|
+
|
469
|
+
df2 = conn.add_deferrable
|
470
|
+
df2.should_receive(:succeed).with("mytube")
|
471
|
+
|
472
|
+
conn.received("WATCHING 24\r\nUSING mytube\r\n")
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'recieving multiple replies in one packet where first is STATS and second is DEADLINE_SOON (anti regression)' do
|
476
|
+
df.should_receive(:succeed).with do |stats|
|
477
|
+
stats['id'].should == 2
|
478
|
+
end
|
479
|
+
|
480
|
+
df2 = conn.add_deferrable
|
481
|
+
df2.should_receive(:fail).with(:deadline_soon)
|
482
|
+
|
483
|
+
conn.received("OK 142\r\n---\nid: 2\ntube: default\nstate: reserved\npri: 65536\nage: 2\ndelay: 0\nttr: 3\ntime-left: 0\nreserves: 1\ntimeouts: 0\nreleases: 0\nburies: 0\nkicks: 0\n\r\nDEADLINE_SOON\r\n")
|
484
|
+
end
|
485
|
+
|
486
|
+
it 'receiving data in chunks' do
|
487
|
+
msg1 = "First half of the message\r\n"
|
488
|
+
msg2 = "Last half of the message"
|
489
|
+
|
490
|
+
df.should_receive(:succeed).with do |job|
|
491
|
+
job.body.should == "#{msg1}#{msg2}"
|
492
|
+
end
|
493
|
+
|
494
|
+
conn.received("RESERVED 9 #{(msg1 + msg2).length}\r\n#{msg1}")
|
495
|
+
conn.received("#{msg2}\r\n")
|
496
|
+
end
|
497
|
+
|
498
|
+
it 'receiving a response broken over multiple packets' do
|
499
|
+
msg1 = "First half of the message\r\n"
|
500
|
+
msg2 = "Last half of the message"
|
501
|
+
|
502
|
+
df.should_receive(:succeed).with do |job|
|
503
|
+
job.body.should == "#{msg1}#{msg2}"
|
504
|
+
end
|
505
|
+
|
506
|
+
conn.received("RESERVED 9 ")
|
507
|
+
conn.received("#{(msg1 + msg2).length}")
|
508
|
+
conn.received("\r\n#{msg1}#{msg2}\r\n")
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'the \r\n in a separate packet' do
|
512
|
+
msg1 = "First half of the message\r\n"
|
513
|
+
msg2 = "Last half of the message"
|
514
|
+
|
515
|
+
df.should_receive(:succeed).with do |job|
|
516
|
+
job.body.should == "#{msg1}#{msg2}"
|
517
|
+
end
|
518
|
+
|
519
|
+
conn.received("RESERVED 9 #{(msg1 + msg2).length}\r\n#{msg1}#{msg2}")
|
520
|
+
conn.received("\r\n")
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
context 'passed blocks' do
|
525
|
+
def callbacks(df)
|
526
|
+
df.instance_variable_get("@callbacks")
|
527
|
+
end
|
528
|
+
|
529
|
+
let (:blk) do
|
530
|
+
Proc.new { "my proc" }
|
531
|
+
end
|
532
|
+
|
533
|
+
describe 'uses #send' do
|
534
|
+
before(:each) do
|
535
|
+
connection_mock.should_receive(:send)
|
536
|
+
end
|
537
|
+
|
538
|
+
it 'use should set the callback when provided a block' do
|
539
|
+
df = conn.use('test', &blk)
|
540
|
+
callbacks(df).include?(blk).should be_true
|
541
|
+
end
|
542
|
+
|
543
|
+
it 'watch should set the callback when provided a block' do
|
544
|
+
df = conn.watch('blarg', &blk)
|
545
|
+
callbacks(df).include?(blk).should be_true
|
546
|
+
end
|
547
|
+
|
548
|
+
it 'ignore should set the callback when provided a block' do
|
549
|
+
conn.instance_variable_get("@watched_tubes").push('blarg')
|
550
|
+
df = conn.ignore('blarg', &blk)
|
551
|
+
callbacks(df).include?(blk).should be_true
|
552
|
+
end
|
553
|
+
|
554
|
+
it 'reserve should set the callback when provided a block' do
|
555
|
+
df = conn.reserve(&blk)
|
556
|
+
callbacks(df).include?(blk).should be_true
|
557
|
+
end
|
558
|
+
|
559
|
+
it 'stats should set the callback when provided a block' do
|
560
|
+
df = conn.stats(&blk)
|
561
|
+
callbacks(df).include?(blk).should be_true
|
562
|
+
end
|
563
|
+
|
564
|
+
it 'list should set the callback when provided a block' do
|
565
|
+
df = conn.list(&blk)
|
566
|
+
callbacks(df).include?(blk).should be_true
|
567
|
+
end
|
568
|
+
|
569
|
+
it 'delete should set the callback when provided a block' do
|
570
|
+
job = EMJack::Job.new(nil, 1, "body")
|
571
|
+
df = conn.delete(job, &blk)
|
572
|
+
callbacks(df).include?(blk).should be_true
|
573
|
+
end
|
574
|
+
|
575
|
+
it 'release should set the callback when provided a block' do
|
576
|
+
job = EMJack::Job.new(nil, 1, "body")
|
577
|
+
df = conn.release(job, &blk)
|
578
|
+
callbacks(df).include?(blk).should be_true
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
it 'put should set the callback when provided a block' do
|
583
|
+
connection_mock.should_receive(:send_with_data)
|
584
|
+
|
585
|
+
df = conn.put("asdf", nil, &blk)
|
586
|
+
callbacks(df).include?(blk).should be_true
|
587
|
+
end
|
588
|
+
end
|
589
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
if RUBY_VERSION > '1.9'
|
4
|
+
require 'fiber'
|
5
|
+
|
6
|
+
describe EMJack::Connection do
|
7
|
+
it "should process live messages" do
|
8
|
+
EM.run do
|
9
|
+
EM.add_timer(10) { EM.stop }
|
10
|
+
|
11
|
+
Fiber.new do
|
12
|
+
bean = EMJack::Connection.new
|
13
|
+
bean.fiber!
|
14
|
+
|
15
|
+
bean.put("hello!")
|
16
|
+
job = bean.reserve
|
17
|
+
job.body.should == "hello!"
|
18
|
+
job.delete
|
19
|
+
|
20
|
+
EM.stop
|
21
|
+
end.resume
|
22
|
+
end
|
23
|
+
end
|
24
|
+
it "should process each job" do
|
25
|
+
EM.run do
|
26
|
+
EM.add_timer(10) { EM.stop }
|
27
|
+
|
28
|
+
job_body = ''
|
29
|
+
|
30
|
+
f = Fiber.new do
|
31
|
+
bean = EMJack::Connection.new
|
32
|
+
bean.fiber!
|
33
|
+
|
34
|
+
bean.put("hello!")
|
35
|
+
bean.put("bonjour!")
|
36
|
+
|
37
|
+
mock = double()
|
38
|
+
mock.should_receive(:foo).with("hello!")
|
39
|
+
mock.should_receive(:foo).with("bonjour!")
|
40
|
+
|
41
|
+
bean.each_job(0) do |job|
|
42
|
+
mock.foo(job.body)
|
43
|
+
job_body = job.body
|
44
|
+
job.delete
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
f.resume
|
50
|
+
|
51
|
+
EM.add_timer(1) { EM.stop unless f.alive?; job_body.should eq "bonjour!" unless f.alive? }
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EMJack::Job do
|
4
|
+
let (:conn ) { mock(:conn) }
|
5
|
+
|
6
|
+
it 'converts jobid to an integer' do
|
7
|
+
j = EMJack::Job.new(nil, "1", "body")
|
8
|
+
j.jobid.class.should == Fixnum
|
9
|
+
j.jobid.should == 1
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'sends a delete command to the connection' do
|
13
|
+
j = EMJack::Job.new(conn, 1, "body")
|
14
|
+
conn.should_receive(:delete).with(j)
|
15
|
+
|
16
|
+
j.delete
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'sends a stats command to the connection' do
|
20
|
+
j = EMJack::Job.new(conn, 2, 'body')
|
21
|
+
conn.should_receive(:stats).with(:job, j)
|
22
|
+
|
23
|
+
j.stats
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'sends a release command to the connection' do
|
27
|
+
blk = Proc.new { x = 1 }
|
28
|
+
|
29
|
+
j = EMJack::Job.new(conn, 2, 'body')
|
30
|
+
conn.should_receive(:release).with(j, {:foo => :bar}, &blk)
|
31
|
+
|
32
|
+
j.release({:foo => :bar}, &blk)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'sends a touch command to the connection' do
|
36
|
+
j = EMJack::Job.new(conn, 2, 'body')
|
37
|
+
conn.should_receive(:touch).with(j)
|
38
|
+
|
39
|
+
j.touch
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'sends a bury command to the connection' do
|
43
|
+
j = EMJack::Job.new(conn, 2, 'body')
|
44
|
+
conn.should_receive(:bury).with(j, 1234)
|
45
|
+
|
46
|
+
j.bury(1234)
|
47
|
+
end
|
48
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,103 +1,123 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-jack
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 3
|
10
|
-
version: 0.1.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.4
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
13
|
-
-
|
7
|
+
authors:
|
8
|
+
- Dan Sinclair
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-02-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: eventmachine
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70242395661740 !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.12.10
|
33
22
|
type: :runtime
|
34
|
-
|
35
|
-
|
36
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70242395661740
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bundler
|
27
|
+
requirement: &70242395661260 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.13
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70242395661260
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70242395660620 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.8.7
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70242395660620
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &70242395660100 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.6'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70242395660100
|
58
|
+
description: An evented Beanstalk client
|
59
|
+
email:
|
60
|
+
- dj2@everburning.com
|
37
61
|
executables: []
|
38
|
-
|
39
62
|
extensions: []
|
40
|
-
|
41
|
-
|
42
|
-
-
|
43
|
-
|
44
|
-
- README.rdoc
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- .gitignore
|
66
|
+
- .rspec
|
45
67
|
- COPYING
|
68
|
+
- Gemfile
|
69
|
+
- README.rdoc
|
70
|
+
- Rakefile
|
71
|
+
- bin/shell
|
72
|
+
- em-jack.gemspec
|
46
73
|
- lib/em-jack.rb
|
47
74
|
- lib/em-jack/beanstalk_connection.rb
|
48
75
|
- lib/em-jack/connection.rb
|
49
76
|
- lib/em-jack/errors.rb
|
50
|
-
- lib/em-jack/job.rb
|
51
77
|
- lib/em-jack/handlers/buried.rb
|
78
|
+
- lib/em-jack/handlers/deleted.rb
|
79
|
+
- lib/em-jack/handlers/errors.rb
|
52
80
|
- lib/em-jack/handlers/inserted.rb
|
81
|
+
- lib/em-jack/handlers/kicked.rb
|
53
82
|
- lib/em-jack/handlers/not_ignored.rb
|
54
83
|
- lib/em-jack/handlers/ok.rb
|
84
|
+
- lib/em-jack/handlers/paused.rb
|
55
85
|
- lib/em-jack/handlers/released.rb
|
56
86
|
- lib/em-jack/handlers/reserved.rb
|
87
|
+
- lib/em-jack/handlers/touched.rb
|
57
88
|
- lib/em-jack/handlers/using.rb
|
58
89
|
- lib/em-jack/handlers/watching.rb
|
59
|
-
- lib/em-jack/
|
60
|
-
- lib/em-jack/
|
61
|
-
-
|
62
|
-
-
|
63
|
-
-
|
64
|
-
|
65
|
-
homepage:
|
90
|
+
- lib/em-jack/job.rb
|
91
|
+
- lib/em-jack/version.rb
|
92
|
+
- spec/em-jack/connection_spec.rb
|
93
|
+
- spec/em-jack/fiber_spec.rb
|
94
|
+
- spec/em-jack/job_spec.rb
|
95
|
+
- spec/spec_helper.rb
|
96
|
+
homepage: https://github.com/dj2/em-jack/
|
66
97
|
licenses: []
|
67
|
-
|
68
98
|
post_install_message:
|
69
|
-
rdoc_options:
|
70
|
-
|
71
|
-
-
|
72
|
-
|
73
|
-
- README.rdoc
|
74
|
-
- --line-numbers
|
75
|
-
require_paths:
|
76
|
-
- lib
|
77
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- - lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
103
|
none: false
|
79
|
-
requirements:
|
80
|
-
- -
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
|
83
|
-
segments:
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
segments:
|
84
109
|
- 0
|
85
|
-
|
86
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
hash: -3983606337964967417
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
112
|
none: false
|
88
|
-
requirements:
|
89
|
-
- -
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
|
92
|
-
segments:
|
93
|
-
- 0
|
94
|
-
version: "0"
|
113
|
+
requirements:
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 1.3.6
|
95
117
|
requirements: []
|
96
|
-
|
97
118
|
rubyforge_project:
|
98
|
-
rubygems_version: 1.
|
119
|
+
rubygems_version: 1.8.10
|
99
120
|
signing_key:
|
100
121
|
specification_version: 3
|
101
|
-
summary: An evented Beanstalk client
|
122
|
+
summary: An evented Beanstalk client
|
102
123
|
test_files: []
|
103
|
-
|