stapfen 2.0.2 → 2.1.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,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: