propono 0.2.0 → 0.3.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.
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