queuel 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.cane +3 -0
- data/.gitignore +1 -1
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile.lock +112 -0
- data/Guardfile +22 -0
- data/README.md +17 -11
- data/Rakefile +7 -0
- data/lib/queuel.rb +50 -27
- data/lib/queuel/base/engine.rb +35 -0
- data/lib/queuel/base/message.rb +32 -0
- data/lib/queuel/base/poller.rb +161 -0
- data/lib/queuel/base/queue.rb +59 -0
- data/lib/queuel/client.rb +15 -3
- data/lib/queuel/configurator.rb +65 -0
- data/lib/queuel/introspect.rb +11 -0
- data/lib/queuel/iron_mq/engine.rb +11 -17
- data/lib/queuel/iron_mq/message.rb +5 -26
- data/lib/queuel/iron_mq/poller.rb +8 -111
- data/lib/queuel/iron_mq/queue.rb +13 -24
- data/lib/queuel/null/engine.rb +3 -7
- data/lib/queuel/null/message.rb +1 -16
- data/lib/queuel/null/poller.rb +2 -114
- data/lib/queuel/null/queue.rb +6 -9
- data/lib/queuel/version.rb +1 -1
- data/queuel.gemspec +10 -0
- data/spec/lib/queuel/base/queue_spec.rb +23 -0
- data/spec/lib/queuel/client_spec.rb +30 -0
- data/spec/lib/queuel/configurator_spec.rb +32 -0
- data/spec/lib/queuel/iron_mq/engine_spec.rb +28 -0
- data/spec/lib/queuel/iron_mq/message_spec.rb +2 -2
- data/spec/lib/queuel/iron_mq/poller_spec.rb +15 -1
- data/spec/lib/queuel/iron_mq/queue_spec.rb +2 -2
- data/spec/lib/queuel_spec.rb +12 -7
- data/spec/spec_helper.rb +4 -0
- data/spec/support/engine_shared_example.rb +4 -2
- data/spec/support/message_shared_example.rb +2 -11
- data/spec/support/poller_shared_example.rb +23 -57
- data/spec/support/queue_shared_example.rb +14 -1
- metadata +163 -4
data/lib/queuel/null/engine.rb
CHANGED
data/lib/queuel/null/message.rb
CHANGED
@@ -1,21 +1,6 @@
|
|
1
|
-
require 'forwardable'
|
2
1
|
module Queuel
|
3
2
|
module Null
|
4
|
-
class Message
|
5
|
-
def initialize(id, body, queue = nil)
|
6
|
-
self.id = id
|
7
|
-
self.body = body
|
8
|
-
self.queue = queue
|
9
|
-
end
|
10
|
-
|
11
|
-
attr_reader :id
|
12
|
-
attr_reader :queue
|
13
|
-
attr_reader :body
|
14
|
-
|
15
|
-
private
|
16
|
-
attr_writer :id
|
17
|
-
attr_writer :queue
|
18
|
-
attr_writer :body
|
3
|
+
class Message < Base::Message
|
19
4
|
end
|
20
5
|
end
|
21
6
|
end
|
data/lib/queuel/null/poller.rb
CHANGED
@@ -1,120 +1,8 @@
|
|
1
1
|
require 'timeout'
|
2
2
|
module Queuel
|
3
3
|
module Null
|
4
|
-
class Poller
|
5
|
-
|
6
|
-
# class
|
7
|
-
def initialize(q, options, block)
|
8
|
-
self.options = options || {}
|
9
|
-
self.block = block
|
10
|
-
self.tries = 0
|
11
|
-
self.continue_looping = true
|
12
|
-
end
|
13
|
-
|
14
|
-
def poll
|
15
|
-
choose_looper do |msg|
|
16
|
-
if msg.nil?
|
17
|
-
tried
|
18
|
-
quit_looping! if break_if_nil? || maxed_tried?
|
19
|
-
sleep(sleep_time)
|
20
|
-
end
|
21
|
-
!msg.nil?
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
protected
|
26
|
-
attr_accessor :tries
|
27
|
-
|
28
|
-
private
|
29
|
-
attr_accessor :queue
|
30
|
-
attr_accessor :args
|
31
|
-
attr_accessor :options
|
32
|
-
attr_accessor :block
|
33
|
-
attr_accessor :continue_looping
|
34
|
-
|
35
|
-
def choose_looper(&loop_block)
|
36
|
-
timeout? ? timeout_looper(loop_block) : looper(loop_block)
|
37
|
-
end
|
38
|
-
|
39
|
-
def timeout_looper(loop_block)
|
40
|
-
Timeout.timeout(timeout) { looper(loop_block) }
|
41
|
-
rescue Timeout::Error
|
42
|
-
false
|
43
|
-
end
|
44
|
-
|
45
|
-
def looper(loop_block)
|
46
|
-
while continue_looping? do
|
47
|
-
loop_block.call(pop_new_message)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def continue_looping?
|
52
|
-
!!continue_looping
|
53
|
-
end
|
54
|
-
|
55
|
-
def quit_looping!
|
56
|
-
self.continue_looping = false
|
57
|
-
end
|
58
|
-
|
59
|
-
def timeout
|
60
|
-
options[:poll_timeout].to_i
|
61
|
-
end
|
62
|
-
|
63
|
-
def timeout?
|
64
|
-
timeout > 0
|
65
|
-
end
|
66
|
-
|
67
|
-
def pop_new_message
|
68
|
-
nil
|
69
|
-
end
|
70
|
-
|
71
|
-
def start_sleep_time
|
72
|
-
0.1
|
73
|
-
end
|
74
|
-
|
75
|
-
def sleep_time
|
76
|
-
tries < 30 ? (start_sleep_time * tries) : 3
|
77
|
-
end
|
78
|
-
|
79
|
-
def reset_tries
|
80
|
-
self.tries = 0
|
81
|
-
end
|
82
|
-
|
83
|
-
def maxed_tried?
|
84
|
-
tries >= max_fails if max_fails_given?
|
85
|
-
end
|
86
|
-
|
87
|
-
def max_fails_given?
|
88
|
-
max_fails > 0
|
89
|
-
end
|
90
|
-
|
91
|
-
def max_fails
|
92
|
-
options[:max_consecutive_fails].to_i
|
93
|
-
end
|
94
|
-
|
95
|
-
def tried
|
96
|
-
self.tries += 1
|
97
|
-
end
|
98
|
-
|
99
|
-
def break_if_nil?
|
100
|
-
!!options.fetch(:break_if_nil, false)
|
101
|
-
end
|
102
|
-
|
103
|
-
def option_keys
|
104
|
-
%w[break_if_nil poll_timeout max_consecutive_fails]
|
105
|
-
end
|
106
|
-
|
107
|
-
def my_options
|
108
|
-
options.select { |key,_| option_keys.include? key.to_s }
|
109
|
-
end
|
110
|
-
|
111
|
-
def built_options
|
112
|
-
options.merge default_args # intentional direction, force defaults
|
113
|
-
end
|
114
|
-
|
115
|
-
def default_args
|
116
|
-
{ n: 1 }
|
117
|
-
end
|
4
|
+
class Poller < Base::Poller
|
5
|
+
alias built_options options
|
118
6
|
end
|
119
7
|
end
|
120
8
|
end
|
data/lib/queuel/null/queue.rb
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
require 'queuel/null/poller'
|
2
2
|
module Queuel
|
3
3
|
module Null
|
4
|
-
class Queue
|
5
|
-
def
|
4
|
+
class Queue < Base::Queue
|
5
|
+
def peek(options = {})
|
6
|
+
[]
|
6
7
|
end
|
7
8
|
|
8
|
-
|
9
|
-
def push(*)
|
9
|
+
def push(message)
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
def receive(options = {}, &block)
|
16
|
-
Poller.new(options, block).poll
|
12
|
+
# Nullify
|
13
|
+
def pop(options = {}, &block)
|
17
14
|
end
|
18
15
|
end
|
19
16
|
end
|
data/lib/queuel/version.rb
CHANGED
data/queuel.gemspec
CHANGED
@@ -24,5 +24,15 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "simplecov"
|
25
25
|
spec.add_development_dependency "iron_mq"
|
26
26
|
spec.add_development_dependency "typhoeus"
|
27
|
+
spec.add_development_dependency "guard-bundler"
|
28
|
+
spec.add_development_dependency "guard-rspec"
|
29
|
+
spec.add_development_dependency "guard-cane"
|
30
|
+
spec.add_development_dependency "rb-inotify"
|
31
|
+
spec.add_development_dependency "rb-fsevent"
|
32
|
+
spec.add_development_dependency "rb-fchange"
|
33
|
+
spec.add_development_dependency "cane"
|
27
34
|
spec.add_development_dependency "json", "~> 1.7.7"
|
35
|
+
|
36
|
+
spec.add_dependency "thread"
|
37
|
+
spec.add_dependency "mono_logger"
|
28
38
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Queuel
|
3
|
+
module Base
|
4
|
+
describe Queue do
|
5
|
+
let(:client) { double "Client" }
|
6
|
+
let(:queue_name) { double "some_queue" }
|
7
|
+
subject { described_class.new client, queue_name }
|
8
|
+
|
9
|
+
its(:thread_count) { should == 1 }
|
10
|
+
|
11
|
+
it "fails on non-impleneted push" do
|
12
|
+
expect { subject.push("") }.to raise_error NotImplementedError
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "polling" do
|
16
|
+
it "delegates polling to a new poller" do
|
17
|
+
Poller.any_instance.should_receive(:poll).once
|
18
|
+
subject.receive { |m| }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -8,6 +8,36 @@ module Queuel
|
|
8
8
|
it { should respond_to :receive }
|
9
9
|
it { should respond_to :with }
|
10
10
|
|
11
|
+
describe "fails without a queue" do
|
12
|
+
it "fails for push" do
|
13
|
+
expect { subject.push }.to raise_error NoQueueGivenError
|
14
|
+
end
|
15
|
+
|
16
|
+
it "fails for pop" do
|
17
|
+
expect { subject.pop }.to raise_error NoQueueGivenError
|
18
|
+
end
|
19
|
+
|
20
|
+
it "fails for receive" do
|
21
|
+
expect { subject.receive }.to raise_error NoQueueGivenError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "fails without a valid name queue" do
|
26
|
+
subject { described_class.new(IronMq::Engine, {}).with " " }
|
27
|
+
|
28
|
+
it "fails for push" do
|
29
|
+
expect { subject.push }.to raise_error NoQueueGivenError
|
30
|
+
end
|
31
|
+
|
32
|
+
it "fails for pop" do
|
33
|
+
expect { subject.pop }.to raise_error NoQueueGivenError
|
34
|
+
end
|
35
|
+
|
36
|
+
it "fails for receive" do
|
37
|
+
expect { subject.receive }.to raise_error NoQueueGivenError
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
11
41
|
describe "queue swapping" do
|
12
42
|
before do
|
13
43
|
Queuel.stub default_queue: "default"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Queuel
|
3
|
+
describe Configurator do
|
4
|
+
describe "configuration" do
|
5
|
+
before do
|
6
|
+
subject.credentials username: "jon"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "set the logger" do
|
10
|
+
subject.logger.should be_a Logger
|
11
|
+
subject.log_level.should == MonoLogger::ERROR
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "configured logger" do
|
15
|
+
let(:some_other_logger) { double "logger" }
|
16
|
+
|
17
|
+
it "fails on a logger without the correct methods" do
|
18
|
+
expect { subject.logger some_other_logger }.to raise_error Configurator::InvalidConfigurationError,
|
19
|
+
"Logger must respond to #{%w[info warn debug level level]}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "set the credentials" do
|
24
|
+
subject.credentials.should == { username: "jon" }
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has a default worker count" do
|
28
|
+
subject.receiver_threads.should == 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -3,6 +3,34 @@ module Queuel
|
|
3
3
|
module IronMq
|
4
4
|
describe Engine do
|
5
5
|
it_should_behave_like "an engine"
|
6
|
+
|
7
|
+
describe "loading typhoeus" do
|
8
|
+
describe "with typhoeus" do
|
9
|
+
before do
|
10
|
+
subject.stub :require do
|
11
|
+
raise LoadError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
its(:try_typhoeus) { should == false }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "without typhoeus" do
|
19
|
+
its(:try_typhoeus) { should == true }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "getting iron client" do
|
24
|
+
its(:client_klass) { should == ::IronMQ::Client }
|
25
|
+
|
26
|
+
describe "undefined" do
|
27
|
+
before do
|
28
|
+
subject.stub defined?: false
|
29
|
+
end
|
30
|
+
|
31
|
+
its(:client_klass) { should == ::IronMQ::Client }
|
32
|
+
end
|
33
|
+
end
|
6
34
|
end
|
7
35
|
end
|
8
36
|
end
|
@@ -5,8 +5,8 @@ module Queuel
|
|
5
5
|
it_should_behave_like "a message"
|
6
6
|
describe "initialization with Iron Object" do
|
7
7
|
let(:queue_double) { double "Queue" }
|
8
|
-
let(:message_object) { double "IronMessage", id: 1,
|
9
|
-
subject { described_class.
|
8
|
+
let(:message_object) { double "IronMessage", id: 1, body: "body", queue: queue_double }
|
9
|
+
subject { described_class.new(message_object) }
|
10
10
|
|
11
11
|
its(:id) { should == 1 }
|
12
12
|
its(:body) { should == "body" }
|
@@ -2,7 +2,21 @@ require 'spec_helper'
|
|
2
2
|
module Queuel
|
3
3
|
module IronMq
|
4
4
|
describe Poller do
|
5
|
-
|
5
|
+
describe "canned behavior" do
|
6
|
+
it_should_behave_like "a poller"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "specific to Iron MQ" do
|
10
|
+
let(:queue) { double "Queue" }
|
11
|
+
let(:options) { {} }
|
12
|
+
let(:block) { double "Callable" }
|
13
|
+
subject { described_class.new queue, block, options }
|
14
|
+
|
15
|
+
describe "its options" do
|
16
|
+
its(:built_options) { should == { n: 1 } }
|
17
|
+
its(:default_options) { should == { n: 1 } }
|
18
|
+
end
|
19
|
+
end
|
6
20
|
end
|
7
21
|
end
|
8
22
|
end
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
module Queuel
|
3
3
|
module IronMq
|
4
4
|
describe Queue do
|
5
|
-
let(:queue_object_with_message) { double "QueueObject", get: message }
|
6
|
-
let(:queue_object_with_nil_message) { double "QueueObject", get: nil }
|
5
|
+
let(:queue_object_with_message) { double "QueueObject", get: message, peek: [message] }
|
6
|
+
let(:queue_object_with_nil_message) { double "QueueObject", get: nil, peek: nil }
|
7
7
|
it_should_behave_like "a queue"
|
8
8
|
end
|
9
9
|
end
|
data/spec/lib/queuel_spec.rb
CHANGED
@@ -9,15 +9,20 @@ describe Queuel do
|
|
9
9
|
it { should respond_to :<< }
|
10
10
|
it { should respond_to :receive }
|
11
11
|
|
12
|
-
describe "
|
13
|
-
|
14
|
-
subject.
|
15
|
-
|
16
|
-
|
12
|
+
describe "engine" do
|
13
|
+
describe "unset settings" do
|
14
|
+
before { subject.instance_variable_set "@config", nil }
|
15
|
+
before { subject.configure { log_level 5 } }
|
16
|
+
its(:engine) { should == Queuel::Null::Engine }
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
describe "with configured" do
|
20
|
+
before do
|
21
|
+
subject.configure { engine :iron_mq }
|
22
|
+
end
|
23
|
+
after { subject.instance_variable_set("@config", nil) }
|
24
|
+
|
25
|
+
its(:engine) { should == Queuel::IronMq::Engine }
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -15,6 +15,10 @@ RSpec.configure do |config|
|
|
15
15
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
16
16
|
config.run_all_when_everything_filtered = true
|
17
17
|
config.filter_run :focus
|
18
|
+
config.filter_run_excluding :perf
|
19
|
+
config.before do
|
20
|
+
Queuel.configure { log_level 5 }
|
21
|
+
end
|
18
22
|
|
19
23
|
# Run specs in random order to surface order dependencies. If you find an
|
20
24
|
# order dependency and want to debug it, you can fix the order by providing
|
@@ -1,10 +1,12 @@
|
|
1
1
|
shared_examples "an engine" do
|
2
2
|
let(:client_object) { double "Client Object" }
|
3
3
|
let(:client) { double "#{described_class.name} Client", new: client_object }
|
4
|
-
let(:queue_const)
|
4
|
+
let(:queue_const) do
|
5
|
+
Object.module_eval("#{described_class.to_s.split("::")[0..-2].join("::")}::Queue",__FILE__,__LINE__)
|
6
|
+
end
|
5
7
|
|
6
8
|
before do
|
7
|
-
subject.stub
|
9
|
+
subject.stub client_klass: client
|
8
10
|
end
|
9
11
|
|
10
12
|
it { should respond_to :queue }
|