qup 1.2.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,140 @@
1
+ require "spec_helper"
2
+ require "tmpdir"
3
+ require "timeout"
4
+
5
+ module Qup
6
+ describe BatchConsumer do
7
+ class Client
8
+ include Qup::BatchConsumerAPI
9
+
10
+ def process(message)
11
+ messages << message.data
12
+ end
13
+
14
+ def messages
15
+ @messages ||= []
16
+ end
17
+ end
18
+
19
+ describe "#new" do
20
+ it "passes options[:session_options] to the session" do
21
+ session_options = double
22
+ batch_consumer = BatchConsumer.new({
23
+ :session_options => session_options,
24
+ :queue_uri => "maildir://#{Dir.mktmpdir}"
25
+ })
26
+ batch_consumer.session.options.should == session_options
27
+ end
28
+ end
29
+
30
+ describe "#run" do
31
+ let(:queue_uri) { "maildir://#{Dir.mktmpdir}" }
32
+ let(:queue_name) { "test" }
33
+ let(:queue) { Session.new(queue_uri).queue(queue_name) }
34
+
35
+ it "doesn't blow up if #setup or #teardown is not defined" do
36
+ queue.producer.produce("A")
37
+
38
+ empty_client = Class.new do
39
+ include Qup::BatchConsumerAPI
40
+
41
+ def process(*)
42
+ end
43
+ end
44
+
45
+ batch_consumer = BatchConsumer.new({
46
+ :max_size => 1,
47
+ :client => empty_client.new,
48
+ :queue_uri => queue_uri,
49
+ :queue_name => queue_name
50
+ })
51
+
52
+ batch_consumer.run
53
+ end
54
+
55
+ it "does blow up if #process isn't defined" do
56
+ queue.producer.produce("A")
57
+
58
+ empty_client = Class.new do
59
+ include Qup::BatchConsumerAPI
60
+ end
61
+
62
+ batch_consumer = BatchConsumer.new({
63
+ :max_size => 1,
64
+ :client => empty_client.new,
65
+ :queue_uri => queue_uri,
66
+ :queue_name => queue_name
67
+ })
68
+
69
+ expect { batch_consumer.run }.to raise_error(NotImplementedError)
70
+ end
71
+
72
+ it "calls process until max_size is met" do
73
+ ["A", "B", "C"].each { |d| queue.producer.produce(d) }
74
+
75
+ client = Client.new
76
+ batch_consumer = BatchConsumer.new({
77
+ :client => client,
78
+ :max_size => 2,
79
+ :queue_uri => queue_uri,
80
+ :queue_name => queue_name
81
+ })
82
+
83
+ batch_consumer.run
84
+ client.messages.should == ["A", "B"]
85
+ end
86
+
87
+ it "returns when max_age is met" do
88
+ client = Client.new
89
+ batch_consumer = BatchConsumer.new({
90
+ :client => client,
91
+ :max_size => 1,
92
+ :max_age => 0.001,
93
+ :queue_uri => queue_uri,
94
+ :queue_name => queue_name
95
+ })
96
+
97
+ Timeout.timeout(1) { batch_consumer.run } # Does not hang
98
+ end
99
+
100
+ it "returns when max_age and max_size are present and one of the values is met" do
101
+
102
+ client = Client.new
103
+
104
+ ["A", "B", "C"].each { |d| queue.producer.produce(d) }
105
+
106
+ batch_consumer = BatchConsumer.new({
107
+ :client => client,
108
+ :max_size => 1,
109
+ :max_age => 5,
110
+ :queue_uri => queue_uri,
111
+ :queue_name => queue_name
112
+ })
113
+
114
+ batch_consumer.run
115
+ client.messages.should == ["A"]
116
+
117
+ end
118
+
119
+
120
+ it "calls the #setup, #process and #teardown in the correct order" do
121
+ queue.producer.produce("A")
122
+
123
+ client = Client.new
124
+
125
+ batch_consumer = BatchConsumer.new({
126
+ :max_size => 1,
127
+ :client => client,
128
+ :queue_uri => queue_uri,
129
+ :queue_name => queue_name
130
+ })
131
+
132
+ client.should_receive(:setup).once.ordered
133
+ client.should_receive(:process).once.ordered
134
+ client.should_receive(:teardown).once.ordered
135
+
136
+ batch_consumer.run
137
+ end
138
+ end
139
+ end
140
+ end
@@ -37,4 +37,11 @@ describe Qup::Consumer do
37
37
  queue.depth.should eq 0
38
38
  end
39
39
 
40
+ it "knows how deep the consumer's queue is" do
41
+ consumer.depth.should eq 1
42
+ consumer.consume do |msg|
43
+ msg.data.should eq 'consumption'
44
+ end
45
+ queue.depth.should eq 0
46
+ end
40
47
  end
@@ -78,4 +78,11 @@ describe Qup::Session do
78
78
  lambda { session.topic( 'boom' ) }.should raise_error( Qup::Session::ClosedError, /Session (.*) is closed/ )
79
79
  end
80
80
  end
81
+
82
+ describe '#options' do
83
+ it "holds the options that are used to initialize the session" do
84
+ s = Qup::Session.open( uri, { :the => 'Option' } )
85
+ s.options[:the].should == 'Option'
86
+ end
87
+ end
81
88
  end
@@ -20,10 +20,17 @@ shared_examples Qup::QueueAPI do
20
20
  queue.name.should eq 'foo'
21
21
  end
22
22
 
23
- it "#produce" do
24
- queue.depth.should eq 0
25
- queue.produce( "a new message" )
26
- queue.depth.should eq 1
23
+ describe "#produce" do
24
+ it "produces an item on the queue" do
25
+ queue.depth.should eq 0
26
+ queue.produce( "a new message" )
27
+ queue.depth.should eq 1
28
+ end
29
+
30
+ it "does not create multiple messages for newlines" do
31
+ queue.produce( "one\nsingle\nmessage" )
32
+ queue.depth.should eq 1
33
+ end
27
34
  end
28
35
 
29
36
  it "#flush" do
@@ -49,6 +56,11 @@ shared_examples Qup::QueueAPI do
49
56
  msg.data.should eq 'consumeable message'
50
57
  end
51
58
  end
59
+
60
+ it 'returns nil if the queue is empty (it is non-blocking)' do
61
+ queue.consume
62
+ queue.consume.should == nil
63
+ end
52
64
  end
53
65
 
54
66
  describe "#acknowledge" do
@@ -53,5 +53,13 @@ shared_examples Qup::TopicAPI do
53
53
  msg.data.should eq 'hi all'
54
54
  end
55
55
  end
56
+
57
+ it "only receive a single message for a message containing newlines" do
58
+ p = @topic.publisher
59
+ p.publish( "one\nsingle\nmessage" )
60
+ @subs.each do |sub|
61
+ sub.depth.should eq 1
62
+ end
63
+ end
56
64
  end
57
65
  end
@@ -1,3 +1,8 @@
1
+ if RUBY_VERSION >= '1.9.2' then
2
+ require 'simplecov'
3
+ SimpleCov.start if ENV['COVERAGE']
4
+ end
5
+
1
6
  require "rspec/autorun"
2
7
  require 'qup'
3
8
 
@@ -15,12 +20,14 @@ RSpec.configure do |conf|
15
20
  Qup::KNOWN_ADAPTERS.each do |adapter, gemname|
16
21
  begin
17
22
  require "qup/adapter/#{adapter}"
18
- rescue LoadError
23
+ rescue LoadError => e
19
24
  warn "NOTICE:"
20
25
  warn "NOTICE: The tests for the '#{adapter}' will be skipped as the '#{gemname}' is not installed"
21
26
  warn "NOTICE:"
27
+ warn "LoadError: #{e}"
22
28
  sym = adapter.to_sym
23
29
  conf.filter_run_excluding sym => true
24
30
  end
25
31
  end
26
32
  end
33
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qup
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 2
8
+ - 4
9
9
  - 0
10
- version: 1.2.0
10
+ version: 1.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Hinegardner
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-03-17 00:00:00 Z
18
+ date: 2012-10-31 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: maildir
@@ -25,28 +25,28 @@ dependencies:
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
- hash: 15
28
+ hash: 11
29
29
  segments:
30
30
  - 2
31
+ - 1
31
32
  - 0
32
- - 0
33
- version: 2.0.0
33
+ version: 2.1.0
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: kestrel-client
37
+ name: kjess
38
38
  prerelease: false
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
43
43
  - !ruby/object:Gem::Version
44
- hash: 1
44
+ hash: 23
45
45
  segments:
46
- - 0
47
- - 7
48
46
  - 1
49
- version: 0.7.1
47
+ - 0
48
+ - 0
49
+ version: 1.0.0
50
50
  type: :development
51
51
  version_requirements: *id002
52
52
  - !ruby/object:Gem::Dependency
@@ -59,32 +59,16 @@ dependencies:
59
59
  - !ruby/object:Gem::Version
60
60
  hash: 3
61
61
  segments:
62
+ - 3
63
+ - 0
62
64
  - 2
63
- - 2
64
- - 2
65
- version: 2.2.2
65
+ version: 3.0.2
66
66
  type: :development
67
67
  version_requirements: *id003
68
- - !ruby/object:Gem::Dependency
69
- name: SystemTimer
70
- prerelease: false
71
- requirement: &id004 !ruby/object:Gem::Requirement
72
- none: false
73
- requirements:
74
- - - ~>
75
- - !ruby/object:Gem::Version
76
- hash: 25
77
- segments:
78
- - 1
79
- - 2
80
- - 3
81
- version: 1.2.3
82
- type: :development
83
- version_requirements: *id004
84
68
  - !ruby/object:Gem::Dependency
85
69
  name: rake
86
70
  prerelease: false
87
- requirement: &id005 !ruby/object:Gem::Requirement
71
+ requirement: &id004 !ruby/object:Gem::Requirement
88
72
  none: false
89
73
  requirements:
90
74
  - - ~>
@@ -97,43 +81,27 @@ dependencies:
97
81
  - 2
98
82
  version: 0.9.2.2
99
83
  type: :development
100
- version_requirements: *id005
101
- - !ruby/object:Gem::Dependency
102
- name: rcov
103
- prerelease: false
104
- requirement: &id006 !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ~>
108
- - !ruby/object:Gem::Version
109
- hash: 23
110
- segments:
111
- - 1
112
- - 0
113
- - 0
114
- version: 1.0.0
115
- type: :development
116
- version_requirements: *id006
84
+ version_requirements: *id004
117
85
  - !ruby/object:Gem::Dependency
118
86
  name: rspec
119
87
  prerelease: false
120
- requirement: &id007 !ruby/object:Gem::Requirement
88
+ requirement: &id005 !ruby/object:Gem::Requirement
121
89
  none: false
122
90
  requirements:
123
91
  - - ~>
124
92
  - !ruby/object:Gem::Version
125
- hash: 47
93
+ hash: 35
126
94
  segments:
127
95
  - 2
128
- - 8
96
+ - 11
129
97
  - 0
130
- version: 2.8.0
98
+ version: 2.11.0
131
99
  type: :development
132
- version_requirements: *id007
100
+ version_requirements: *id005
133
101
  - !ruby/object:Gem::Dependency
134
102
  name: rdoc
135
103
  prerelease: false
136
- requirement: &id008 !ruby/object:Gem::Requirement
104
+ requirement: &id006 !ruby/object:Gem::Requirement
137
105
  none: false
138
106
  requirements:
139
107
  - - ~>
@@ -144,7 +112,7 @@ dependencies:
144
112
  - 12
145
113
  version: "3.12"
146
114
  type: :development
147
- version_requirements: *id008
115
+ version_requirements: *id006
148
116
  description: Qup is a generalized API for Message Queue and Publish/Subscribe messaging patterns with the ability to plug in an appropriate messaging infrastructure based upon your needs. Qup ships with support for Kestrel, Redis, and a filesystem infrastructure based on Maildir. Additional Adapters will be developed as needs arise. Please submit an Issue to have a new Adapter created. Pull requests gladly accepted.
149
117
  email: jeremy@copiousfreetime.org
150
118
  executables: []
@@ -177,6 +145,8 @@ files:
177
145
  - lib/qup/adapter/redis/connection.rb
178
146
  - lib/qup/adapter/redis/queue.rb
179
147
  - lib/qup/adapter/redis/topic.rb
148
+ - lib/qup/backoff_sleeper.rb
149
+ - lib/qup/batch_consumer.rb
180
150
  - lib/qup/consumer.rb
181
151
  - lib/qup/message.rb
182
152
  - lib/qup/producer.rb
@@ -198,6 +168,8 @@ files:
198
168
  - spec/qup/adapter/redis_context.rb
199
169
  - spec/qup/adapter/redis_spec.rb
200
170
  - spec/qup/adapter_spec.rb
171
+ - spec/qup/backoff_sleeper_sleeper_spec.rb
172
+ - spec/qup/batch_consumer_spec.rb
201
173
  - spec/qup/consumer_spec.rb
202
174
  - spec/qup/message_spec.rb
203
175
  - spec/qup/producer_spec.rb
@@ -241,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
241
213
  requirements: []
242
214
 
243
215
  rubyforge_project:
244
- rubygems_version: 1.8.16
216
+ rubygems_version: 1.8.24
245
217
  signing_key:
246
218
  specification_version: 3
247
219
  summary: Qup is a generalized API for Message Queue and Publish/Subscribe messaging patterns with the ability to plug in an appropriate messaging infrastructure based upon your needs.
@@ -259,6 +231,8 @@ test_files:
259
231
  - spec/qup/adapter/redis_context.rb
260
232
  - spec/qup/adapter/redis_spec.rb
261
233
  - spec/qup/adapter_spec.rb
234
+ - spec/qup/backoff_sleeper_sleeper_spec.rb
235
+ - spec/qup/batch_consumer_spec.rb
262
236
  - spec/qup/consumer_spec.rb
263
237
  - spec/qup/message_spec.rb
264
238
  - spec/qup/producer_spec.rb