qup 1.2.0 → 1.4.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.
@@ -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