propono 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d088866567c48097ae184895e09ead7de705179d
4
- data.tar.gz: c6f6e90ed8d3c1773e95e1c7d60c211274df48d9
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDE0YzRiMzE2ZmNkZGU3NGIwODc4YzkxMjljNWFiMGM0MDEwM2U3OA==
5
+ data.tar.gz: !binary |-
6
+ N2Y4YTI2YmY3NWM3ZTA0MjJlZWJkMjkxNGQxMGYwZDlkNDI4NzE0Zg==
5
7
  SHA512:
6
- metadata.gz: b39237981ffd1d4c3515247ea61db476633f810e8de97308ec76a25efb4b5a0d6e9db71196c15b9250a88b6dee657f1ccc22940916c87619df8e14547e06f33f
7
- data.tar.gz: 60bffaf2b6bd7f07189c5b3d441db887b90720ca3d1c5e5365895b407757943289b40c564b0a9244db1a805125b69e78dc534dd19382b6d302890cda3deb3cc7
8
+ metadata.gz: !binary |-
9
+ MGM3Mzg3NmZmZjIzYjZjMTUyODMzMzM1ZGZlNDRhNjYwNzkzMzE4ZTI0ODA4
10
+ YzJlNzc5OGE2MzMyNDY0MWViYTVlZjNmODIyMGIyMGY0OWE1ZDgxOThiYWI5
11
+ NGFlMjIzYTAxNzcxZTBhYzQ0YmE5ZTQ2NzYyNDViNDYzNGNhMzc=
12
+ data.tar.gz: !binary |-
13
+ MGJkYTU1YTBlZTI4ZWJlZWMwZDcyZjg3NWNmOTBlOGU5YjMyYTcxOTI1OGZm
14
+ MTczNGM2NDE2MDJlZDQ4ZjY5ZDc4NWE2MWU4YWRmODUzZWI2MzQ3OGZlYzIx
15
+ OGE1ZmJkY2U1OGI5ODFmMWRlYTJkYjliYjRkZGJmOWUxYTkxZTc=
data/lib/propono.rb CHANGED
@@ -8,6 +8,7 @@ require "propono/components/topic"
8
8
  require "propono/services/post_subscriber"
9
9
  require "propono/services/publisher"
10
10
  require "propono/services/queue_creator"
11
+ require "propono/services/queue_listener"
11
12
  require "propono/services/queue_subscriber"
12
13
  require "propono/services/subscriber"
13
14
  require "propono/services/topic_creator"
@@ -29,4 +30,8 @@ module Propono
29
30
  Subscriber.subscribe_by_post(*args)
30
31
  end
31
32
 
33
+ def self.listen_to_queue(*args, &block)
34
+ QueueListener.listen(*args, &block)
35
+ end
36
+
32
37
  end
@@ -8,10 +8,17 @@ module Propono
8
8
  class Configuration
9
9
  include Singleton
10
10
 
11
- SETTINGS = [:access_key, :secret_key, :queue_region, :application_name]
11
+ SETTINGS = [
12
+ :access_key,
13
+ :secret_key,
14
+ :queue_region,
15
+ :application_name,
16
+ :logger
17
+ ]
12
18
  attr_writer *SETTINGS
13
19
 
14
20
  def initialize
21
+ self.logger = $stderr
15
22
  end
16
23
 
17
24
  SETTINGS.each do |setting|
@@ -0,0 +1,45 @@
1
+ module Propono
2
+ class QueueListener
3
+
4
+ include Sqs
5
+
6
+ def self.listen(queue_url, &block)
7
+ new(queue_url, &block).listen
8
+ end
9
+
10
+ def initialize(queue_url, &block)
11
+ @queue_url = queue_url
12
+ @block = block
13
+ end
14
+
15
+ def listen
16
+ loop {
17
+ sleep 10 unless read_messages
18
+ }
19
+ end
20
+
21
+ private
22
+
23
+ def read_messages
24
+ begin
25
+ response = sqs.receive_message( @queue_url, options = { 'MaxNumberOfMessages' => 10 } )
26
+ messages = response.body['Message']
27
+ if messages.empty?
28
+ false
29
+ else
30
+ process_messages(messages)
31
+ end
32
+ rescue
33
+ config.logger.puts "Unexpected error reading from queue #{@queue_url}"
34
+ end
35
+ end
36
+
37
+ def process_messages(messages)
38
+ messages.each do |message|
39
+ @block.call(message)
40
+ sqs.delete_message(message['ReceiptHandle'])
41
+ end
42
+ true
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  module Propono
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,98 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Propono
4
+ class QueueListenerTest < Minitest::Test
5
+
6
+ def setup
7
+ @queue_url = "http://example.com"
8
+
9
+ @receipt_hanlde1 = "test-receipt-handle1"
10
+ @receipt_hanlde2 = "test-receipt-handle2"
11
+ @message1 = { "ReceiptHandle" => @receipt_handle1}
12
+ @message2 = { "ReceiptHandle" => @receipt_handle2}
13
+ @messages = { "Message" => [ @message1, @message2 ] }
14
+ end
15
+
16
+ def test_read_message_from_sqs
17
+ message_response = mock()
18
+ messages = { "Message" => [ { "ReceiptHandle" => "test-receipt-handle"} ] }
19
+ message_response.expects(:body).returns(messages)
20
+ sqs = mock()
21
+ sqs.stubs(delete_message: message_response)
22
+
23
+ sqs.expects(:receive_message).returns(message_response)
24
+
25
+ queueListener = QueueListener.new(@queue_url) {}
26
+ queueListener.stubs(sqs: sqs)
27
+
28
+ queueListener.send(:read_messages)
29
+ end
30
+
31
+ def test_each_message_yielded
32
+ message_response = mock()
33
+ message_response.expects(:body).returns(@messages)
34
+ sqs = mock()
35
+ sqs.stubs(receive_message: message_response)
36
+
37
+ sqs.expects(:delete_message).with(@receipt_handle1)
38
+ sqs.expects(:delete_message).with(@receipt_handle2)
39
+
40
+ queueListener = QueueListener.new(@queue_url) { }
41
+ queueListener.stubs(sqs: sqs)
42
+
43
+ queueListener.send(:read_messages)
44
+ end
45
+
46
+ def test_each_message_deleted_from_sqs
47
+ message_response = mock()
48
+ message_response.expects(:body).returns(@messages)
49
+ sqs = mock()
50
+ sqs.stubs(delete_message: message_response)
51
+ sqs.stubs(receive_message: message_response)
52
+
53
+ messages_yielded = [ ]
54
+ queueListener = QueueListener.new(@queue_url) { |m| messages_yielded.push(m) }
55
+ queueListener.stubs(sqs: sqs)
56
+
57
+ queueListener.send(:read_messages)
58
+
59
+ assert_equal messages_yielded.size, 2
60
+ assert messages_yielded.include?(@message1)
61
+ assert messages_yielded.include?(@message2)
62
+ end
63
+
64
+ def test_empty_list_of_messages_returned
65
+ message_response = mock()
66
+ messages = { "Message" => [ ] }
67
+ message_response.expects(:body).returns(messages)
68
+ sqs = mock()
69
+ sqs.stubs(delete_message: message_response)
70
+
71
+ sqs.expects(:receive_message).returns(message_response)
72
+
73
+ queueListener = QueueListener.new(@queue_url) {}
74
+ queueListener.stubs(sqs: sqs)
75
+
76
+ refute queueListener.send(:read_messages)
77
+ end
78
+
79
+ def test_exception_from_sqs_is_logged
80
+ sqs = mock()
81
+ sqs.stubs(:receive_message).raises(StandardError)
82
+
83
+ queueListener = QueueListener.new(@queue_url) {}
84
+ queueListener.stubs(sqs: sqs)
85
+
86
+ # capture_io reasigns stderr. Assign the config.logger
87
+ # to where capture_io has redirected it to for this test.
88
+ out, err = capture_io do
89
+ config.logger = $stderr
90
+ queueListener.send(:read_messages)
91
+ end
92
+ # Reassign config.logger to the correct stderr
93
+ config.logger = $stderr
94
+ assert_equal "Unexpected error reading from queue http://example.com\n", err
95
+ end
96
+
97
+ end
98
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propono
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - MalcyL
@@ -15,14 +15,14 @@ dependencies:
15
15
  name: fog
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - '>='
18
+ - - ! '>='
19
19
  - !ruby/object:Gem::Version
20
20
  version: '0'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - '>='
25
+ - - ! '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
28
  - !ruby/object:Gem::Dependency
@@ -43,28 +43,28 @@ dependencies:
43
43
  name: rake
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - '>='
46
+ - - ! '>='
47
47
  - !ruby/object:Gem::Version
48
48
  version: '0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - '>='
53
+ - - ! '>='
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: mocha
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - '>='
60
+ - - ! '>='
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - '>='
67
+ - - ! '>='
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  - !ruby/object:Gem::Dependency
@@ -105,6 +105,7 @@ files:
105
105
  - lib/propono/services/post_subscriber.rb
106
106
  - lib/propono/services/publisher.rb
107
107
  - lib/propono/services/queue_creator.rb
108
+ - lib/propono/services/queue_listener.rb
108
109
  - lib/propono/services/queue_subscriber.rb
109
110
  - lib/propono/services/subscriber.rb
110
111
  - lib/propono/services/topic_creator.rb
@@ -114,6 +115,7 @@ files:
114
115
  - test/post_subscriber_test.rb
115
116
  - test/publisher_test.rb
116
117
  - test/queue_creator_test.rb
118
+ - test/queue_listener_test.rb
117
119
  - test/queue_subscriber_test.rb
118
120
  - test/queue_test.rb
119
121
  - test/sns_test.rb
@@ -132,17 +134,17 @@ require_paths:
132
134
  - lib
133
135
  required_ruby_version: !ruby/object:Gem::Requirement
134
136
  requirements:
135
- - - '>='
137
+ - - ! '>='
136
138
  - !ruby/object:Gem::Version
137
139
  version: '0'
138
140
  required_rubygems_version: !ruby/object:Gem::Requirement
139
141
  requirements:
140
- - - '>='
142
+ - - ! '>='
141
143
  - !ruby/object:Gem::Version
142
144
  version: '0'
143
145
  requirements: []
144
146
  rubyforge_project:
145
- rubygems_version: 2.0.0
147
+ rubygems_version: 2.1.9
146
148
  signing_key:
147
149
  specification_version: 4
148
150
  summary: General purpose pub/sub library built on top of AWS SNS and SQS
@@ -151,6 +153,7 @@ test_files:
151
153
  - test/post_subscriber_test.rb
152
154
  - test/publisher_test.rb
153
155
  - test/queue_creator_test.rb
156
+ - test/queue_listener_test.rb
154
157
  - test/queue_subscriber_test.rb
155
158
  - test/queue_test.rb
156
159
  - test/sns_test.rb