propono 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +11 -8
- data/lib/propono/components/queue_subscription.rb +27 -1
- data/lib/propono/services/queue_listener.rb +20 -11
- data/lib/propono/version.rb +1 -1
- data/test/components/queue_subscription_test.rb +10 -1
- data/test/integration/slow_queue_test.rb +47 -0
- data/test/services/queue_listener_test.rb +45 -16
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc75e2e19f1d9e8fa2ca756f46652573e37e594c
|
4
|
+
data.tar.gz: 4c69d41b50a1a8789a914eff5f6c6bfed7cec2b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b9b480054550f9b89702d960c0334ce4a379709e35789a2915da49de36239d9ede8f55b66675bc31b4ad628a738e9574b730b311ec1082b8a804529f5d55f9b
|
7
|
+
data.tar.gz: 5716632a5a337f4fe101a5ec9dc08e66d4fced1191fa77d479a28688e91f8a30ec3fc624494f4696c99537ebbb1754f42906c0a0cbbe6790ac82c65d51c05219
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -48,7 +48,7 @@ Propono.publish('some-topic', "Some string")
|
|
48
48
|
Propono.publish('some-topic', {some: ['hash', 'or', 'array']})
|
49
49
|
```
|
50
50
|
|
51
|
-
Listening for messages is easy too. Just tell Propono what your application is called and start listening. You'll get a block
|
51
|
+
Listening for messages is easy too. Just tell Propono what your application is called and start listening. You'll get a block yielded for each message.
|
52
52
|
|
53
53
|
```ruby
|
54
54
|
Propono.config.application_name = "application-name" # Something unique to this app.
|
@@ -56,11 +56,13 @@ Propono.listen_to_queue('some-topic') do |message|
|
|
56
56
|
# ... Do something interesting with the message
|
57
57
|
end
|
58
58
|
```
|
59
|
-
In the background, Propono is automatically setting up a queue using SQS, a notification system using SNS, and
|
59
|
+
In the background, Propono is automatically setting up a queue using SQS, a notification system using SNS, and gluing them all together for you. But you don't have to worry about any of that.
|
60
|
+
|
61
|
+
**Note for using in Rake tasks and similar:** Propono spawns new threads for messages sent via SNS. If your application ends before the final thread is executed, then the last message might not send. It's therefore advisable to do a `Thread.join` on the thread that is returned from the final call to `publish`.
|
60
62
|
|
61
63
|
### Using TCP for messages
|
62
64
|
|
63
|
-
Publishing directly to SNS takes about 15x longer than publishing over a simple TCP connection. It is therefore
|
65
|
+
Publishing directly to SNS takes about 15x longer than publishing over a simple TCP connection. It is therefore sometimes favourable to publish to a separate machine listening for TCP messages, which will then proxy them on.
|
64
66
|
|
65
67
|
To send messages this way, you need to set up a little extra config:
|
66
68
|
|
@@ -91,7 +93,7 @@ Propono.proxy_tcp()
|
|
91
93
|
|
92
94
|
### Using UDP for messages
|
93
95
|
|
94
|
-
If you want almost-zero performance impact, and don't mind the occasional message getting lost, you can use UDP. We use this for things like our live dashboard where we don't mind losing a piece of activity here and there, but any
|
96
|
+
If you want almost-zero performance impact, and don't mind the occasional message getting lost, you can use UDP. We use this for things like our live dashboard where we don't mind losing a piece of activity here and there, but any performance impact on our Meducation itself is bad news.
|
95
97
|
|
96
98
|
Sending messages in this way is very similar to using TCP. First add some config:
|
97
99
|
|
@@ -106,7 +108,7 @@ You then simply pass the `:udp` protocol into `publish`:
|
|
106
108
|
Propono.publish('some-topic', message, protocol: :udp)
|
107
109
|
```
|
108
110
|
|
109
|
-
As per the `listen_to_tcp` method explained above, you now listen to
|
111
|
+
As per the `listen_to_tcp` method explained above, you now listen to UDP or use the proxy method:
|
110
112
|
|
111
113
|
```ruby
|
112
114
|
Propono.listen_to_udp do |topic, message|
|
@@ -134,7 +136,7 @@ Propono.config do |config|
|
|
134
136
|
end
|
135
137
|
```
|
136
138
|
|
137
|
-
|
139
|
+
These can all also be set using the `Propono.config.access_key = "..."` syntax.
|
138
140
|
|
139
141
|
### Is it any good?
|
140
142
|
|
@@ -152,8 +154,9 @@ This project is managed by the [Meducation team](http://company.meducation.net/a
|
|
152
154
|
|
153
155
|
These individuals have come up with the ideas and written the code that made this possible:
|
154
156
|
|
155
|
-
- [Jeremy Walker](http://github.com/
|
156
|
-
- [
|
157
|
+
- [Jeremy Walker](http://github.com/iHiD)
|
158
|
+
- [Malcolm Landon](http://github.com/malcyL)
|
159
|
+
- [Charles Care](http://github.com/ccare)
|
157
160
|
- [Rob Styles](http://github.com/mmmmmrob)
|
158
161
|
|
159
162
|
## Licence
|
@@ -4,7 +4,7 @@ module Propono
|
|
4
4
|
include Sns
|
5
5
|
include Sqs
|
6
6
|
|
7
|
-
attr_reader :topic_arn, :queue_name, :queue, :failed_queue, :corrupt_queue
|
7
|
+
attr_reader :topic_arn, :queue_name, :queue, :failed_queue, :corrupt_queue, :slow_queue
|
8
8
|
|
9
9
|
def self.create(topic_id, options = {})
|
10
10
|
new(topic_id, options).tap do |subscription|
|
@@ -15,6 +15,7 @@ module Propono
|
|
15
15
|
def initialize(topic_id, options = {})
|
16
16
|
@topic_id = topic_id
|
17
17
|
@suffixed_topic_id = "#{topic_id}#{Propono.config.queue_suffix}"
|
18
|
+
@suffixed_slow_topic_id = "#{topic_id}#{Propono.config.queue_suffix}-slow"
|
18
19
|
@queue_name = "#{Propono.config.application_name.gsub(" ", "_")}-#{@suffixed_topic_id}"
|
19
20
|
end
|
20
21
|
|
@@ -26,6 +27,11 @@ module Propono
|
|
26
27
|
@corrupt_queue = QueueCreator.find_or_create("#{queue_name}-corrupt")
|
27
28
|
sns.subscribe(@topic.arn, @queue.arn, 'sqs')
|
28
29
|
sqs.set_queue_attributes(@queue.url, "Policy", generate_policy)
|
30
|
+
|
31
|
+
@slow_queue = QueueCreator.find_or_create("#{queue_name}-slow")
|
32
|
+
@slow_topic = TopicCreator.find_or_create(@suffixed_slow_topic_id)
|
33
|
+
sns.subscribe(@slow_topic.arn, @slow_queue.arn, 'sqs')
|
34
|
+
sqs.set_queue_attributes(@slow_queue.url, "Policy", generate_slow_policy)
|
29
35
|
end
|
30
36
|
|
31
37
|
private
|
@@ -46,6 +52,26 @@ module Propono
|
|
46
52
|
"Resource": "#{@queue.arn}"
|
47
53
|
}
|
48
54
|
]
|
55
|
+
}
|
56
|
+
EOS
|
57
|
+
end
|
58
|
+
|
59
|
+
def generate_slow_policy
|
60
|
+
<<-EOS
|
61
|
+
{
|
62
|
+
"Version": "2008-10-17",
|
63
|
+
"Id": "#{@slow_queue.arn}/SQSDefaultPolicy",
|
64
|
+
"Statement": [
|
65
|
+
{
|
66
|
+
"Sid": "#{@slow_queue.arn}-Sid",
|
67
|
+
"Effect": "Allow",
|
68
|
+
"Principal": {
|
69
|
+
"AWS": "*"
|
70
|
+
},
|
71
|
+
"Action": "SQS:*",
|
72
|
+
"Resource": "#{@slow_queue.arn}"
|
73
|
+
}
|
74
|
+
]
|
49
75
|
}
|
50
76
|
EOS
|
51
77
|
end
|
@@ -24,12 +24,16 @@ module Propono
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def read_messages
|
27
|
-
|
27
|
+
read_messages_from_queue(main_queue_url, 10) || read_messages_from_queue(slow_queue_url, 1)
|
28
|
+
end
|
29
|
+
|
30
|
+
def read_messages_from_queue(queue_url, num_messages)
|
31
|
+
response = sqs.receive_message(queue_url, {'MaxNumberOfMessages' => num_messages} )
|
28
32
|
messages = response.body['Message']
|
29
33
|
if messages.empty?
|
30
34
|
false
|
31
35
|
else
|
32
|
-
messages.each { |msg| process_raw_message(msg) }
|
36
|
+
messages.each { |msg| process_raw_message(msg, queue_url) }
|
33
37
|
end
|
34
38
|
rescue Excon::Errors::Forbidden
|
35
39
|
Propono.config.logger.error "Forbidden error caught and re-raised. #{queue_url}"
|
@@ -44,21 +48,21 @@ module Propono
|
|
44
48
|
# as to ensure the message is only deleted if the preceeding line
|
45
49
|
# has completed succesfully. We do *not* want to ensure that the
|
46
50
|
# message is deleted regardless of what happens in this method.
|
47
|
-
def process_raw_message(raw_sqs_message)
|
48
|
-
sqs_message = parse(raw_sqs_message)
|
51
|
+
def process_raw_message(raw_sqs_message, queue_url)
|
52
|
+
sqs_message = parse(raw_sqs_message, queue_url)
|
49
53
|
unless sqs_message.nil?
|
50
54
|
Propono.config.logger.info "Propono [#{sqs_message.context[:id]}]: Received from sqs."
|
51
55
|
handle(sqs_message)
|
52
|
-
delete_message(raw_sqs_message)
|
56
|
+
delete_message(raw_sqs_message, queue_url)
|
53
57
|
end
|
54
58
|
end
|
55
59
|
|
56
|
-
def parse(raw_sqs_message)
|
60
|
+
def parse(raw_sqs_message, queue_url)
|
57
61
|
SqsMessage.new(raw_sqs_message)
|
58
62
|
rescue
|
59
63
|
Propono.config.logger.error "Error parsing message, moving to corrupt queue", $!, $!.backtrace
|
60
64
|
move_to_corrupt_queue(raw_sqs_message)
|
61
|
-
delete_message(raw_sqs_message)
|
65
|
+
delete_message(raw_sqs_message, queue_url)
|
62
66
|
nil
|
63
67
|
end
|
64
68
|
|
@@ -78,17 +82,17 @@ module Propono
|
|
78
82
|
end
|
79
83
|
|
80
84
|
def requeue_message_on_failure(sqs_message, exception)
|
81
|
-
next_queue = (sqs_message.failure_count < Propono.config.max_retries) ?
|
85
|
+
next_queue = (sqs_message.failure_count < Propono.config.max_retries) ? main_queue_url : failed_queue_url
|
82
86
|
Propono.config.logger.error "Error proessing message, moving to queue: #{next_queue}"
|
83
87
|
sqs.send_message(next_queue, sqs_message.to_json_with_exception(exception))
|
84
88
|
end
|
85
89
|
|
86
|
-
def delete_message(raw_sqs_message)
|
90
|
+
def delete_message(raw_sqs_message, queue_url)
|
87
91
|
sqs.delete_message(queue_url, raw_sqs_message['ReceiptHandle'])
|
88
92
|
end
|
89
93
|
|
90
|
-
def
|
91
|
-
@
|
94
|
+
def main_queue_url
|
95
|
+
@main_queue_url ||= subscription.queue.url
|
92
96
|
end
|
93
97
|
|
94
98
|
def failed_queue_url
|
@@ -99,8 +103,13 @@ module Propono
|
|
99
103
|
@corrupt_queue_url ||= subscription.corrupt_queue.url
|
100
104
|
end
|
101
105
|
|
106
|
+
def slow_queue_url
|
107
|
+
@slow_queue_url ||= subscription.slow_queue.url
|
108
|
+
end
|
109
|
+
|
102
110
|
def subscription
|
103
111
|
@subscription ||= QueueSubscription.create(@topic_id)
|
104
112
|
end
|
113
|
+
|
105
114
|
end
|
106
115
|
end
|
data/lib/propono/version.rb
CHANGED
@@ -16,7 +16,10 @@ module Propono
|
|
16
16
|
def test_create_topic
|
17
17
|
topic_id = 'foobar'
|
18
18
|
topic = Topic.new(topic_id)
|
19
|
+
slow_topic_id = 'foobar-slow'
|
20
|
+
slow_topic = Topic.new(slow_topic_id)
|
19
21
|
TopicCreator.expects(:find_or_create).with("#{topic_id}#{@suffix}").returns(topic)
|
22
|
+
TopicCreator.expects(:find_or_create).with("#{topic_id}#{@suffix}-slow").returns(slow_topic)
|
20
23
|
QueueSubscription.create(topic_id)
|
21
24
|
end
|
22
25
|
|
@@ -32,6 +35,7 @@ module Propono
|
|
32
35
|
sqs.expects(:create_queue).with(queue_name).returns(mock(body: {'QueueUrl' => Fog::AWS::SQS::Mock::QueueUrl}))
|
33
36
|
sqs.expects(:create_queue).with(queue_name + '-failed').returns(mock(body: {'QueueUrl' => Fog::AWS::SQS::Mock::QueueUrl}))
|
34
37
|
sqs.expects(:create_queue).with(queue_name + '-corrupt').returns(mock(body: {'QueueUrl' => Fog::AWS::SQS::Mock::QueueUrl}))
|
38
|
+
sqs.expects(:create_queue).with(queue_name + '-slow').returns(mock(body: {'QueueUrl' => Fog::AWS::SQS::Mock::QueueUrl}))
|
35
39
|
QueueCreator.any_instance.stubs(sqs: sqs)
|
36
40
|
|
37
41
|
subscription.create
|
@@ -62,7 +66,7 @@ module Propono
|
|
62
66
|
QueueCreator.stubs(find_or_create: Queue.new(Fog::AWS::SQS::Mock::QueueUrl))
|
63
67
|
|
64
68
|
sns = mock()
|
65
|
-
sns.expects(:subscribe).with(arn, Fog::AWS::SQS::Mock::QueueArn, 'sqs')
|
69
|
+
sns.expects(:subscribe).with(arn, Fog::AWS::SQS::Mock::QueueArn, 'sqs').twice
|
66
70
|
subscription = QueueSubscription.new("Some topic")
|
67
71
|
subscription.stubs(sns: sns)
|
68
72
|
subscription.create
|
@@ -71,15 +75,18 @@ module Propono
|
|
71
75
|
def test_create_calls_set_queue_attributes
|
72
76
|
arn = "arn123"
|
73
77
|
policy = "{foobar: 123}"
|
78
|
+
slow_policy = "{foobar: 456}"
|
74
79
|
|
75
80
|
TopicCreator.stubs(find_or_create: Topic.new(arn))
|
76
81
|
QueueCreator.stubs(find_or_create: Queue.new(Fog::AWS::SQS::Mock::QueueUrl))
|
77
82
|
|
78
83
|
sqs = mock()
|
79
84
|
sqs.expects(:set_queue_attributes).with(Fog::AWS::SQS::Mock::QueueUrl, "Policy", policy)
|
85
|
+
sqs.expects(:set_queue_attributes).with(Fog::AWS::SQS::Mock::QueueUrl, "Policy", slow_policy)
|
80
86
|
subscription = QueueSubscription.new("Some topic")
|
81
87
|
subscription.stubs(sqs: sqs)
|
82
88
|
subscription.stubs(generate_policy: policy)
|
89
|
+
subscription.stubs(generate_slow_policy: slow_policy)
|
83
90
|
subscription.create
|
84
91
|
end
|
85
92
|
|
@@ -87,10 +94,12 @@ module Propono
|
|
87
94
|
queue = Queue.new(Fog::AWS::SQS::Mock::QueueUrl)
|
88
95
|
failed_queue = Queue.new(Fog::AWS::SQS::Mock::QueueUrl)
|
89
96
|
corrupt_queue = Queue.new(Fog::AWS::SQS::Mock::QueueUrl)
|
97
|
+
slow_queue = Queue.new(Fog::AWS::SQS::Mock::QueueUrl)
|
90
98
|
|
91
99
|
QueueCreator.expects(:find_or_create).with('MyApp-SomeTopic-suf').returns(queue)
|
92
100
|
QueueCreator.expects(:find_or_create).with('MyApp-SomeTopic-suf-failed').returns(failed_queue)
|
93
101
|
QueueCreator.expects(:find_or_create).with('MyApp-SomeTopic-suf-corrupt').returns(corrupt_queue)
|
102
|
+
QueueCreator.expects(:find_or_create).with('MyApp-SomeTopic-suf-slow').returns(slow_queue)
|
94
103
|
subscription = QueueSubscription.new("SomeTopic")
|
95
104
|
subscription.create
|
96
105
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.expand_path('../integration_test', __FILE__)
|
2
|
+
|
3
|
+
module Propono
|
4
|
+
class SlowQueueTest < IntegrationTest
|
5
|
+
def test_slow_messages_are_received
|
6
|
+
topic = "slow-test-topic"
|
7
|
+
slow_topic = "slow-test-topic-slow"
|
8
|
+
text = "This is my message #{DateTime.now} #{rand()}"
|
9
|
+
slow_text = "This is my slow message #{DateTime.now} #{rand()}"
|
10
|
+
flunks = []
|
11
|
+
message_received = false
|
12
|
+
slow_message_received = false
|
13
|
+
|
14
|
+
Propono.subscribe_by_queue(topic)
|
15
|
+
|
16
|
+
thread = Thread.new do
|
17
|
+
begin
|
18
|
+
Propono.listen_to_queue(topic) do |message, context|
|
19
|
+
flunks << "Wrong message" unless (message == text || message == slow_text)
|
20
|
+
message_received = true if message == text
|
21
|
+
slow_message_received = true if message == slow_text
|
22
|
+
end
|
23
|
+
rescue => e
|
24
|
+
flunks << e.message
|
25
|
+
ensure
|
26
|
+
thread.terminate
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Thread.new do
|
31
|
+
sleep(1) while !message_received
|
32
|
+
sleep(1) while !slow_message_received
|
33
|
+
sleep(5) # Make sure all the message deletion clear up in the thread has happened
|
34
|
+
thread.terminate
|
35
|
+
end
|
36
|
+
|
37
|
+
sleep(1) # Make sure the listener has started
|
38
|
+
|
39
|
+
Propono.publish(slow_topic, slow_text)
|
40
|
+
Propono.publish(topic, text)
|
41
|
+
flunks << "Test Timeout" unless wait_for_thread(thread)
|
42
|
+
flunk(flunks.join("\n")) unless flunks.empty?
|
43
|
+
ensure
|
44
|
+
# thread.terminate
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -47,44 +47,49 @@ module Propono
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def test_read_message_from_sqs
|
50
|
-
queue_url = @listener.send(:
|
50
|
+
queue_url = @listener.send(:main_queue_url)
|
51
51
|
options = { 'MaxNumberOfMessages' => 10 }
|
52
52
|
@sqs.expects(:receive_message).with(queue_url, options).returns(@sqs_response)
|
53
|
-
@listener.send(:
|
53
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
54
54
|
end
|
55
55
|
|
56
56
|
def test_log_message_from_sqs
|
57
|
+
queue_url = @listener.send(:main_queue_url)
|
57
58
|
Propono.config.logger.expects(:info).with() {|x| x == "Propono [#{@message1_id}]: Received from sqs."}
|
58
|
-
@listener.send(:
|
59
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
59
60
|
end
|
60
61
|
|
61
62
|
def test_read_messages_calls_process_message_for_each_msg
|
62
|
-
@listener.
|
63
|
-
@listener.expects(:process_raw_message).with(@
|
64
|
-
@listener.
|
63
|
+
queue_url = @listener.send(:main_queue_url)
|
64
|
+
@listener.expects(:process_raw_message).with(@sqs_message1, queue_url)
|
65
|
+
@listener.expects(:process_raw_message).with(@sqs_message2, queue_url)
|
66
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
65
67
|
end
|
66
68
|
|
67
69
|
def test_read_messages_does_not_call_process_messages_if_there_are_none
|
70
|
+
queue_url = @listener.send(:main_queue_url)
|
68
71
|
@sqs_response.stubs(body: {"Message" => []})
|
69
72
|
@listener.expects(:process_message).never
|
70
|
-
@listener.send(:
|
73
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
71
74
|
end
|
72
75
|
|
73
76
|
def test_exception_from_sqs_is_logged
|
74
|
-
|
77
|
+
queue_url = "http://example.com"
|
78
|
+
@listener.stubs(main_queue_url: queue_url)
|
75
79
|
@sqs.stubs(:receive_message).raises(StandardError)
|
76
80
|
Propono.config.logger.expects(:error).with("Unexpected error reading from queue http://example.com")
|
77
81
|
Propono.config.logger.expects(:error).with() {|x| x.is_a?(StandardError)}
|
78
|
-
@listener.send(:
|
82
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
79
83
|
end
|
80
84
|
|
81
85
|
def test_forbidden_error_is_logged_and_re_raised
|
82
|
-
|
86
|
+
queue_url = "http://example.com"
|
87
|
+
@listener.stubs(queue_url: queue_url)
|
83
88
|
@sqs.stubs(:receive_message).raises(Excon::Errors::Forbidden.new(nil, nil, nil))
|
84
89
|
Propono.config.logger.expects(:error).with("Forbidden error caught and re-raised. http://example.com")
|
85
90
|
Propono.config.logger.expects(:error).with() {|x| x.is_a?(Excon::Errors::Forbidden)}
|
86
91
|
assert_raises Excon::Errors::Forbidden do
|
87
|
-
@listener.send(:
|
92
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
88
93
|
end
|
89
94
|
end
|
90
95
|
|
@@ -122,7 +127,7 @@ module Propono
|
|
122
127
|
@sqs.expects(:delete_message).with(queue_url, @receipt_handle2)
|
123
128
|
|
124
129
|
@listener.stubs(queue_url: queue_url)
|
125
|
-
@listener.send(:
|
130
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
126
131
|
end
|
127
132
|
|
128
133
|
def test_messages_are_deleted_if_there_is_an_exception_processing
|
@@ -137,19 +142,23 @@ module Propono
|
|
137
142
|
@listener.stubs(sqs: @sqs)
|
138
143
|
@listener.stubs(:requeue_message_on_failure).with(SqsMessage.new(@sqs_message1), exception)
|
139
144
|
@listener.stubs(:requeue_message_on_failure).with(SqsMessage.new(@sqs_message2), exception)
|
140
|
-
@listener.send(:
|
145
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
141
146
|
end
|
142
147
|
|
143
148
|
def test_messages_are_retried_or_abandoned_on_failure
|
149
|
+
queue_url = "test-queue-url"
|
150
|
+
|
144
151
|
exception = StandardError.new("Test Error")
|
145
152
|
@listener = QueueListener.new(@topic_id) { raise exception }
|
146
153
|
@listener.expects(:requeue_message_on_failure).with(SqsMessage.new(@sqs_message1), exception)
|
147
154
|
@listener.expects(:requeue_message_on_failure).with(SqsMessage.new(@sqs_message2), exception)
|
148
155
|
@listener.stubs(sqs: @sqs)
|
149
|
-
@listener.send(:
|
156
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
150
157
|
end
|
151
158
|
|
152
159
|
def test_failed_on_moving_to_failed_queue_does_not_delete
|
160
|
+
queue_url = "test-queue-url"
|
161
|
+
|
153
162
|
exception = StandardError.new("Test Error")
|
154
163
|
@listener = QueueListener.new(@topic_id) { raise exception }
|
155
164
|
@listener.stubs(:requeue_message_on_failure).with(SqsMessage.new(@sqs_message1), exception).raises(StandardError.new("failed to move"))
|
@@ -157,10 +166,11 @@ module Propono
|
|
157
166
|
@listener.expects(:delete_message).with(@sqs_message1).never
|
158
167
|
@listener.expects(:delete_message).with(@sqs_message2).never
|
159
168
|
@listener.stubs(sqs: @sqs)
|
160
|
-
@listener.send(:
|
169
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
161
170
|
end
|
162
171
|
|
163
172
|
def test_messages_are_moved_to_corrupt_queue_if_there_is_an_parsing_exception
|
173
|
+
queue_url = "test-queue-url"
|
164
174
|
sqs_message1 = "foobar"
|
165
175
|
sqs_message2 = "barfoo"
|
166
176
|
@messages["Message"][0] = sqs_message1
|
@@ -168,7 +178,7 @@ module Propono
|
|
168
178
|
|
169
179
|
@listener.expects(:move_to_corrupt_queue).with(sqs_message1)
|
170
180
|
@listener.expects(:move_to_corrupt_queue).with(sqs_message2)
|
171
|
-
@listener.send(:
|
181
|
+
@listener.send(:read_messages_from_queue, queue_url, 10)
|
172
182
|
end
|
173
183
|
|
174
184
|
def test_message_moved_to_failed_queue_if_there_is_an_exception_and_retry_count_is_zero
|
@@ -196,5 +206,24 @@ module Propono
|
|
196
206
|
@sqs.expects(:send_message).with(regexp_matches(/https:\/\/queue.amazonaws.com\/[0-9]+\/MyApp-some-topic-corrupt/), anything)
|
197
207
|
@listener.send(:move_to_corrupt_queue, @sqs_message1)
|
198
208
|
end
|
209
|
+
|
210
|
+
def test_if_no_messages_read_from_normal_queue_read_from_slow_queue
|
211
|
+
main_queue_url = "http://normal.com"
|
212
|
+
@listener.stubs(main_queue_url: main_queue_url)
|
213
|
+
slow_queue_url = "http://slow.com"
|
214
|
+
@listener.stubs(slow_queue_url: slow_queue_url)
|
215
|
+
|
216
|
+
@listener.expects(:read_messages_from_queue).with(main_queue_url, 10).returns(false)
|
217
|
+
@listener.expects(:read_messages_from_queue).with(slow_queue_url, 1)
|
218
|
+
@listener.send(:read_messages)
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_if_read_messages_from_normal_do_not_read_from_slow_queue
|
222
|
+
main_queue_url = "http://normal.com"
|
223
|
+
@listener.stubs(main_queue_url: main_queue_url)
|
224
|
+
|
225
|
+
@listener.expects(:read_messages_from_queue).with(main_queue_url, 10).returns(true)
|
226
|
+
@listener.send(:read_messages)
|
227
|
+
end
|
199
228
|
end
|
200
229
|
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: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MalcyL
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-02-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
@@ -144,6 +144,7 @@ files:
|
|
144
144
|
- test/configuration_test.rb
|
145
145
|
- test/helpers/hash_test.rb
|
146
146
|
- test/integration/integration_test.rb
|
147
|
+
- test/integration/slow_queue_test.rb
|
147
148
|
- test/integration/sns_to_sqs_test.rb
|
148
149
|
- test/integration/tcp_to_sqs_test.rb
|
149
150
|
- test/integration/udp_proxy_test.rb
|
@@ -178,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
179
|
version: '0'
|
179
180
|
requirements: []
|
180
181
|
rubyforge_project:
|
181
|
-
rubygems_version: 2.1
|
182
|
+
rubygems_version: 2.2.1
|
182
183
|
signing_key:
|
183
184
|
specification_version: 4
|
184
185
|
summary: General purpose pub/sub library built on top of AWS SNS and SQS
|
@@ -194,6 +195,7 @@ test_files:
|
|
194
195
|
- test/configuration_test.rb
|
195
196
|
- test/helpers/hash_test.rb
|
196
197
|
- test/integration/integration_test.rb
|
198
|
+
- test/integration/slow_queue_test.rb
|
197
199
|
- test/integration/sns_to_sqs_test.rb
|
198
200
|
- test/integration/tcp_to_sqs_test.rb
|
199
201
|
- test/integration/udp_proxy_test.rb
|