stapfen 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZmQzNmFhNTgxODI5ZTM1ZTQ4NTJkYzg4NTRhNmY5N2ZlOGZjMWM4OQ==
4
+ YWZmOWJmNmUzNmU2MDA1MmUzZDJhOGM5ZmRlMDMwOGZjMmU5YWM4MA==
5
5
  data.tar.gz: !binary |-
6
- OTQ0OGI2NjE5MmY3ZDAyMzU0Yzc2M2IyYjljNGE0NDNjYjUzMTkzYg==
6
+ NGM4ODgxMTUwMjFhZTQyYTE3ZjgxODgzOThlMDYzYjcxN2JjMGUyMg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- N2U5NDc0Y2UxOGNkZjY1NDcxMzg2ZDM5ZTg5NjMyZDY2YjkxYmFlMmZlNzQw
10
- MDA1OThiOTYxZDBiZDU3N2MyY2FhZWEzMGQxYTQ4NTY1NzE1OWJiMGQxZTg4
11
- ZDU1ODUyZTI4ZmEwMTE4MzIyOTg4ZjcwMDZmMTIxZTJhMGU2OGQ=
9
+ ZTU4OTgyZmFkY2EyZTAwYmEyNDQxMWI3NjhkOTNiNTA0MGIwOWM2ZDM5NzY3
10
+ NTQ4ZDVlYTAxYWM1YWJjOTQxYzIwNWI1Zjk4OGFjN2ZlN2QwMTAxZGEzYzMz
11
+ M2YwNDdiMWQwODkzMmEyOWMwM2M3OTQyMDVkNzEyNDY1NDZjOWE=
12
12
  data.tar.gz: !binary |-
13
- ODg5Y2EzMjBmNDY5MjI3NmI5Mzg0N2VlMjIyNDk5MGFkNzg0ZTVmMzk1MTEy
14
- ZDI3MjRmNTgxNjFiMmU1NWI3NmQ0YjkzODQ4MWRiN2ViYjczNzdmNGU2ZmIy
15
- NjEyYTZlZmJlODhmZTJlNDMyOTE0NDE2NTQ4MTdjZWJkY2U0MzA=
13
+ NjNhOTRiNjcwMWY4YjRkNThhOWJkYzM4ZTZmZDAzNTA5NjQ4YmQzOGEzYjJl
14
+ YmJiMGE4MDZmMGJjMmQ1MDYyNDVlODA2ZDQxZWIwMzVmOWE1YTA4ZTMxYmY4
15
+ NDg0OTc0ZjlmZmU2ZGM5MjAwNjhlYzFhYTM1NTk1ZmNiZDM2YzU=
data/README.md CHANGED
@@ -73,14 +73,14 @@ It is also important to note that the `consume` block will be invoked inside an
73
73
  **instance** of `MyWorker` and will execute inside its own `Thread`, so take
74
74
  care when accessing other shared resources.
75
75
 
76
- ### STOMP-specific support
77
-
78
- The consume block accepts the usual
79
- [Stomp::Client](https://github.com/stompgem/stomp) subscription headers, as well
80
- as :dead_letter_queue and :max\_redeliveries. If either of the latter two is
81
- present, the consumer will unreceive any messages for which the block returns
82
- false; after :max\_redeliveries, it will send the message to :dead_letter_queue.
83
- `consume` blocks without these headers will fail silently rather than unreceive.
76
+ ### Fallback and dead-letter-queue support
77
+
78
+ The consume block accepts the usual subscriptions headers, as well as two
79
+ additional headers `:dead_letter_queue` and `:max_redeliveries`. If either of
80
+ the latter two is present, the honsumer will unreceive any messages for which
81
+ the block returns `false`; after `:max\_redeliveries`, it will send the message
82
+ to `:dead_letter_queue`. `consume` blocks without these headers will fail
83
+ silently rather than unreceive.
84
84
 
85
85
 
86
86
  ## Installation
@@ -84,7 +84,40 @@ module Stapfen
84
84
  end
85
85
 
86
86
  def can_unreceive?
87
- false
87
+ true
88
+ end
89
+
90
+ # JMS doesn't implement unreceive in quite the way Stomp does, so we'll
91
+ # implement it here.
92
+ #
93
+ # Given a message and a set of unreceive headers, this will deliver the
94
+ # message back to its originating queue a limited number of times, then
95
+ # failover to the dead letter queue.
96
+ #
97
+ # @param [Stapfen::Message] message The message to unreceive.
98
+ # @param [Hash] unreceive_headers
99
+ # @option unreceive_headers [Integer] :max_redeliveries The number of times
100
+ # to attempt redelivery.
101
+ # @option unreceive_headers [String] :dead_letter_queue After giving up on
102
+ # redelivering, send the message here.
103
+ def unreceive(message, unreceive_headers)
104
+ return if unreceive_headers[:max_redeliveries].nil? && unreceive_headers[:max_redeliveries].nil?
105
+
106
+ headers = message.headers
107
+ retry_count = headers.delete('retry_count').to_i || 0
108
+ retry_count += 1
109
+ headers['retry_count'] = retry_count
110
+
111
+ destination = headers.delete('destination')
112
+
113
+ if unreceive_headers[:max_redeliveries] && (retry_count <= unreceive_headers[:max_redeliveries])
114
+ self.publish(destination, message.body, headers)
115
+ elsif unreceive_headers[:dead_letter_queue] # Done retrying, send to DLQ
116
+ headers['original_destination'] = destination
117
+ headers.delete('retry_count')
118
+
119
+ self.publish(unreceive_headers[:dead_letter_queue], message.body, headers)
120
+ end
88
121
  end
89
122
  end
90
123
  end
@@ -1,3 +1,3 @@
1
1
  module Stapfen
2
- VERSION = '2.0.2'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -12,7 +12,110 @@ if RUBY_PLATFORM == 'java'
12
12
  describe '#can_unreceive?' do
13
13
  subject { client.can_unreceive? }
14
14
 
15
- it { should_not be_true }
15
+ it { should be_true }
16
+ end
17
+
18
+ describe '#unreceive' do
19
+ let(:body) { 'Some body in string form' }
20
+ let(:message) { double('Message', :headers => msg_headers.merge('destination' => orig_destination), :body => body) }
21
+ let(:max_redeliveries) { 2 }
22
+ let(:dlq) { '/queue/some_queue/dlq' }
23
+ let(:unreceive_headers) do
24
+ { :dead_letter_queue => dlq, :max_redeliveries => max_redeliveries }
25
+ end
26
+ let(:orig_destination) { '/queue/some_queue' }
27
+
28
+ # Just to make sure we preserve any headers we don't explicitly get rid of
29
+ let(:orig_headers) do
30
+ { 'key1' => 'value1' }
31
+ end
32
+
33
+
34
+ subject(:unreceive!) { client.unreceive(message, unreceive_headers) }
35
+
36
+ context 'with no unreceive[:max_redeliveries] or unreceive[:dead_letter_queue]' do
37
+ let(:msg_headers) { orig_headers }
38
+ let(:unreceive_headers) { Hash.new }
39
+
40
+ it 'should not resend the message' do
41
+ client.should_not_receive(:publish)
42
+
43
+ unreceive!
44
+ end
45
+ end
46
+
47
+ context 'On a message with no retry_count in the headers' do
48
+ let(:msg_headers) { orig_headers }
49
+
50
+ it 'should publish it to the same destination with a retry_count of 1' do
51
+ client.should_receive(:publish) do |dest, the_body, the_headers|
52
+ expect(dest).to eql orig_destination
53
+ expect(the_body).to eql body
54
+ expect(the_headers).to eql msg_headers.merge({'retry_count' => 1})
55
+ end
56
+
57
+ unreceive!
58
+ end
59
+ end
60
+
61
+ context 'On a message with a retry_count in the headers' do
62
+ let(:msg_headers) { orig_headers.merge('retry_count' => retry_count) }
63
+
64
+ context 'that is less than max_redeliveries' do
65
+ let(:retry_count) { max_redeliveries - 1 }
66
+
67
+ it 'should publish it to the same destination with a retry_count increased by one' do
68
+ client.should_receive(:publish) do |dest, the_body, the_headers|
69
+ expect(dest).to eql orig_destination
70
+ expect(the_body).to eql body
71
+
72
+
73
+ expect(the_headers).to eql msg_headers.merge({'retry_count' => retry_count + 1})
74
+ end
75
+
76
+ unreceive!
77
+ end
78
+ end
79
+
80
+ # This is the 'last' attempt to redeliver, so don't send it again
81
+ context 'that is equal to max_redeliveries' do
82
+ let(:retry_count) { max_redeliveries }
83
+
84
+ it 'should publish it to the DLQ with no retry_count' do
85
+ client.should_receive(:publish) do |dest, the_body, the_headers|
86
+ expect(the_body).to eql body
87
+ expect(dest).to eql dlq
88
+
89
+ # Headers should eql msg_headers except for retry count,
90
+ # and original_destination
91
+ msg_headers.delete('retry_count')
92
+ msg_headers['original_destination'] = orig_destination
93
+ expect(the_headers).to eql msg_headers
94
+ end
95
+
96
+ unreceive!
97
+ end
98
+ end
99
+
100
+ context 'that is greater than max_redeliveries' do
101
+ let(:retry_count) { max_redeliveries + 1 }
102
+
103
+ it 'should publish it to the DLQ with no retry_count' do
104
+ client.should_receive(:publish) do |dest, the_body, the_headers|
105
+ expect(the_body).to eql body
106
+ expect(dest).to eql dlq
107
+
108
+ # Headers should eql msg_headers except for retry count,
109
+ # and original_destination
110
+ msg_headers.delete('retry_count')
111
+ msg_headers['original_destination'] = orig_destination
112
+ expect(the_headers).to eql msg_headers
113
+ end
114
+
115
+ unreceive!
116
+ end
117
+ end
118
+ end
16
119
  end
17
120
 
18
121
  describe '#connect' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stapfen
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - R. Tyler Croy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-12 00:00:00.000000000 Z
11
+ date: 2014-01-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple gem for writing good basic STOMP workers
14
14
  email: