nebulous_stomp 2.0.1 → 2.0.2

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,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 210d0ff5d3c99590ab6356e5456e2fa67e9ab0ae
4
- data.tar.gz: ac6782c4ef1969f7f0854de505a393927487cd00
3
+ metadata.gz: a4ac7c514b6d925e6186924b2dd93a175de94e02
4
+ data.tar.gz: 8aca7aa180be4c84fe6ccbe89b172980cd2a56a1
5
5
  SHA512:
6
- metadata.gz: e12b2880dff2e61135575fcb2f694315621fcd8a69f29156e01eec0d1248b8f679241d1907bf75da452ec3bb6cf69152009e364ed9aeaa218b2735c929a7daf2
7
- data.tar.gz: 2e5a0161b8c527dd8633562d1f359b781e105554a4c4d396c2dcba265f78750c0697051d0049cc9f26e6ef060b68cc97358d358e64a6caa1d0a64d3065922f92
6
+ metadata.gz: abb4de512e2aec3d8720505f9f06d7a00b2d5aa4caba2a1e9dab977f6c36cb6970f791289509cc6fbe96b945d6eeec84a65d7fe86b54d7402b97104dcd71c18d
7
+ data.tar.gz: 3e44c452fa7f94cd331cfc637b90b427c5171bd7fa9663b4ebe5118320e8d1ea8554628b57bcecfcc55cbc2f7f69aed9d13f49951c8e1ce82836db55cb7b26d5
data/.hgtags CHANGED
@@ -16,3 +16,4 @@ cff04defabb0895ff2f032087b97ea9616bee6a9 1.14
16
16
  6ddf180c9a2fc1cef55f5d128faa4d5df28d1353 1.1.5
17
17
  6da65ce15fab9722deb05d8c0ed2d0c8e2cfe2ff 2.0.0
18
18
  9c4ec9af8f6b8a848082bf118be037696ff357c7 2.0.1
19
+ 63eb0028eeedf7cc3938fd8ecda1add9246fb905 2.02
@@ -18,18 +18,6 @@ module NebulousStomp
18
18
  # The target name as set up by call to Nebulous::add_target
19
19
  attr_reader :target
20
20
 
21
- # The 'verb' part of the message
22
- attr_reader :verb
23
-
24
- # The 'parameters' part of the message
25
- attr_reader :params
26
-
27
- # The 'description' part of the message
28
- attr_reader :desc
29
-
30
- # The 'replyID' header to use in this message
31
- attr_reader :replyID
32
-
33
21
  # Message timeout in seconds
34
22
  attr_reader :mTimeout
35
23
 
@@ -73,21 +61,23 @@ module NebulousStomp
73
61
  NebulousStomp.logger.debug(__FILE__) {"New NebRequest for verb #{verb}"}
74
62
 
75
63
  @target = target.to_s
76
- @verb = verb.to_s
77
- @params = params.nil? ? nil : params.to_s
78
- @desc = desc.nil? ? nil : desc.to_s
79
64
  @stomp_handler = stompHandler
80
65
  @redis_handler = redisHandler
81
66
  @requestQ = nil
82
67
  @responseQ = nil
83
68
  @message = nil
84
- @replyID = nil
85
69
  @mTimeout = 0
86
70
  @cTimeout = 0
87
71
 
72
+ xverb = verb.to_s
73
+ xparams = params.nil? ? nil : params.to_s
74
+ xdesc = desc.nil? ? nil : desc.to_s
75
+
88
76
  @redis_handler ||= RedisHandler.new( Param.get(:redisConnectHash) )
89
77
  @stomp_handler ||= StompHandler.new( Param.get(:stompConnectHash) )
90
78
 
79
+ neb_setup if nebulous_on?
80
+ @message = Message.from_parts(@responseQ, nil, xverb, xparams, xdesc)
91
81
  neb_connect if nebulous_on?
92
82
  end
93
83
 
@@ -112,7 +102,7 @@ module NebulousStomp
112
102
 
113
103
  # If we've lost the connection then reconnect but *keep replyID*
114
104
  @stomp_handler.stomp_connect unless @stomp_handler.connected?
115
- @replyID = @stomp_handler.calc_reply_id if @replyID.nil?
105
+ @message.reply_id = @stomp_handler.calc_reply_id if @message.reply_id.nil?
116
106
 
117
107
  neb_qna(mTimeout)
118
108
 
@@ -201,14 +191,23 @@ module NebulousStomp
201
191
  end
202
192
 
203
193
 
194
+ #
195
+ # Some of our attributes are actually on Message
196
+ #
197
+
198
+ def verb; @message ? @message.verb : nil; end
199
+ def params; @message ? @message.params : nil; end
200
+ def desc; @message ? @message.desc : nil; end
201
+ def replyID; @message ? @message.reply_id : nil; end
202
+
203
+
204
204
  private
205
205
 
206
206
 
207
207
  ##
208
208
  # Connect to STOMP etc and do initial setup
209
- # Called automatically by initialize, if Nebulous is 'on' in the config.
210
209
  #
211
- def neb_connect
210
+ def neb_setup
212
211
  targetHash = Param.get_target(@target)
213
212
  raise NebulousError, "Unknown target #{target}" if targetHash.nil?
214
213
 
@@ -216,11 +215,16 @@ module NebulousStomp
216
215
  @mTimeout = targetHash[:messageTimeout] || Param.get(:messageTimeout)
217
216
  @requestQ = targetHash[:sendQueue]
218
217
  @responseQ = targetHash[:receiveQueue]
219
- @message = Message.from_parts(@responseQ, nil, verb, params, desc)
220
218
 
221
- @stomp_handler.stomp_connect
222
- @replyID = @stomp_handler.calc_reply_id
219
+ self
220
+ end
223
221
 
222
+
223
+ # Called automatically by initialize, if Nebulous is 'on' in the config.
224
+ #
225
+ def neb_connect
226
+ @stomp_handler.stomp_connect
227
+ @message.reply_id = @stomp_handler.calc_reply_id
224
228
  self
225
229
  end
226
230
 
@@ -236,7 +240,12 @@ module NebulousStomp
236
240
 
237
241
  response = nil
238
242
  @stomp_handler.listen_with_timeout(@responseQ, mTimeout) do |msg|
239
- response = msg
243
+ if replyID && msg.in_reply_to != replyID
244
+ false
245
+ else
246
+ response = msg
247
+ true
248
+ end
240
249
  end
241
250
 
242
251
  response
@@ -17,11 +17,15 @@ module NebulousStomp
17
17
  ##
18
18
  # Initialise an instance of the handler by passing it the connection hash
19
19
  #
20
+ # If no hash is passed, we try and get it from Nebulous::Params
21
+ #
20
22
  # We use the optional testRedis parameter to mock connections to Redis, for
21
23
  # testing. It's probably of no use to anyone else.
22
24
  #
23
- def initialize(connectHash, testRedis=nil)
24
- @redis_hash = connectHash ? connectHash.dup : nil
25
+ def initialize(connectHash=nil, testRedis=nil)
26
+ @redis_hash = connectHash ? connectHash.dup : nil
27
+ @redis_hash ||= Param.get(:redisConnectHash)
28
+
25
29
  @test_redis = testRedis
26
30
  @redis = nil
27
31
  end
@@ -110,10 +110,14 @@ module NebulousStomp
110
110
 
111
111
  ##
112
112
  # Initialise StompHandler by passing the parameter hash.
113
+ #
114
+ # If no hash is set we try and get it from NebulousStomp::Param.
113
115
  # ONLY set testClient when testing.
114
116
  #
115
- def initialize(connectHash, testClient=nil)
116
- @stomp_hash = connectHash ? connectHash.dup : nil
117
+ def initialize(connectHash=nil, testClient=nil)
118
+ @stomp_hash = connectHash ? connectHash.dup : nil
119
+ @stomp_hash ||= Param.get(:stompConnectHash)
120
+
117
121
  @test_client = testClient
118
122
  @client = nil
119
123
  end
@@ -207,11 +211,13 @@ module NebulousStomp
207
211
  ##
208
212
  # As listen() but give up after yielding a single message, and only wait
209
213
  # for a set number of seconds before giving up anyway.
210
- #--
211
- # Ideally I'd like to DRY this and listen() up, but with this
212
- # yield-within-a-thread stuff going on, I'm actually not sure how to do
213
- # that safely.
214
- #++
214
+ #
215
+ # The behaviour here is slightly different than listen(). If you return true from your block,
216
+ # the message will be consumed and the method will end. Otherwise it will continue until it
217
+ # sees another message, or reaches the timeout.
218
+ #
219
+ # Put another way, since most things are truthy -- if you want to examine messages to find the
220
+ # right one, return false from the block to get another.
215
221
  #
216
222
  def listen_with_timeout(queue, timeout)
217
223
  return unless nebulous_on?
@@ -230,11 +236,13 @@ module NebulousStomp
230
236
  @client.subscribe( queue, {ack: "client-individual"} ) do |msg|
231
237
 
232
238
  begin
233
- unless msg.body == "boo"
234
- yield Message.from_stomp(msg)
235
- done = true
239
+ if msg.body == "boo"
240
+ @client.ack(msg)
241
+ else
242
+ done = yield Message.from_stomp(msg)
243
+ @client.ack(msg) if done
236
244
  end
237
- @client.ack(msg)
245
+
238
246
  rescue =>e
239
247
  NebulousStomp.logger.error(__FILE__) {"Error during polling: #{e}" }
240
248
  end
@@ -1,5 +1,5 @@
1
1
  module NebulousStomp
2
2
 
3
3
  # Nebulous version number
4
- VERSION = "2.0.1"
4
+ VERSION = "2.0.2"
5
5
  end
@@ -1,59 +1,51 @@
1
1
  Nebulous: The Protocol
2
2
  ======================
3
3
 
4
- (It was going to be "The Nebulous Protocol", but that sounds like something with
5
- Matt Damon in it.)
4
+ (It was going to be "The Nebulous Protocol", but that sounds like something with Matt Damon in it.)
6
5
 
7
6
 
8
7
  Introduction
9
8
  ------------
10
- Project Nebulous is a STOMP client written in ABL, and also the protocol that
11
- allows our different systems, ABL or not, to pass messages. This document,
12
- obviously, concentrates on the protocol.
9
+ Project Nebulous is a STOMP client written in ABL, and also the protocol that allows our different
10
+ systems, ABL or not, to pass messages. This document, obviously, concentrates on the protocol.
13
11
 
14
- The basic idea is this: one system passes a message, a _request_; and then
15
- waits for an answer to that message, a _response_, from another system. STOMP
16
- doesn't explicitly support that; the protocol does it.
12
+ The basic idea is this: one system passes a message, a _request_; and then waits for an answer to
13
+ that message, a _response_, from another system. STOMP doesn't explicitly support that; the
14
+ protocol does it.
17
15
 
18
- (Note that a request and a response are just notional terms; you might in
19
- theory have a request which provokes a response which provokes another response
20
- in return, in which case the second message is both a response and a request,
21
- and the terms get rather less useful.)
16
+ (Note that a request and a response are just notional terms; you might in theory have a request
17
+ which provokes a response which provokes another response in return, in which case the second
18
+ message is both a response and a request, and the terms get rather less useful.)
22
19
 
23
20
 
24
21
  The Protocol
25
22
  ------------
26
- Let's start with the actual protocol, the rules. They won't make sense without
27
- reading the rest of the document, but:
23
+ Let's start with the actual protocol, the rules. They won't make sense without reading the rest of the document, but:
28
24
 
29
- 1. Every valid request (that is, every message with an identifiable verb other
30
- than "success" or "error") will always generate a response. If the handling
31
- routine cannot generate a valid response, or if there is no routine to handle
32
- the verb in question, then the response should be the error verb. If no
33
- response is required, you should still receive the success verb.
25
+ 1. Every valid request (that is, every message with an identifiable verb other than "success" or
26
+ "error") will always generate a response. If the handling routine cannot generate a valid
27
+ response, or if there is no routine to handle the verb in question, then the response should be
28
+ the error verb. If no response is required, you should still receive the success verb.
34
29
 
35
- 2. You should expect that requests that do not have a verb will not be responded
36
- to or even understood. (However, there is no general requirement for message
37
- bodies to follow the verb / parameters / description format. If you have a
38
- program that sends a request and waits for a response, the format of that
39
- response is outside the remit of The Protocol.)
30
+ 2. You should expect that requests that do not have a verb will not be responded to or even
31
+ understood. (However, there is no general requirement for message bodies to follow the verb /
32
+ parameters / description format. If you have a program that sends a request and waits for a
33
+ response, the format of that response is outside the remit of The Protocol.)
40
34
 
41
- 3. If a request has the _neb-reply-to_ header, the response should use that as
42
- a destination; otherwise it should be sent to the same destination that the
43
- request was sent to.
35
+ 3. If a request has the _neb-reply-to_ header, the response should use that as a destination;
36
+ otherwise it should be sent to the same destination that the request was sent to.
44
37
 
45
- 4. If the request has a _neb-reply-id_ header, then the response should set the
46
- _neb-in-reply-to_ header to that.
38
+ 4. If the request has a _neb-reply-id_ header, then the response should set the _neb-in-reply-to_
39
+ header to that.
47
40
 
48
- 5. The request may specify the content type of a response (JSON or text) by
49
- it's own content type. That is, if a response can be in either form, it
50
- should take the form of the request as an indication as which to use.
41
+ 5. The request may specify the content type of a response (JSON or text) by it's own content type.
42
+ That is, if a response can be in either form, it should take the form of the request as an
43
+ indication as which to use.
51
44
 
52
- 6. A given queue that is the target of requests within The Protocol will be for
53
- only one system or common group of systems. They may consume (ACK) messages
54
- sent to it even if they do not have the facility to process them. If
55
- multiple systems share a queue, they should understand that messages will be
56
- consumed from it at random.
45
+ 6. A given queue that is the target of requests within The Protocol will be for only one system or
46
+ common group of systems. They may consume (ACK) messages sent to it even if they do not have the
47
+ facility to process them. If multiple systems share a queue, they should understand that
48
+ messages will be consumed from it at random.
57
49
 
58
50
 
59
51
  Components
@@ -64,130 +56,112 @@ By way of an explanation of the above section.
64
56
 
65
57
  STOMP allows you to define custom headers. We have three.
66
58
 
67
- * _neb-reply-to_ is may be set on a request to the destination that any
68
- response should be posted to.
59
+ * _neb-reply-to_ is may be set on a request to the destination that any response should be posted
60
+ to. (See rule 3.)
69
61
 
70
- * _neb-reply-id_ may be set on a request to an arbitrary string to help
71
- you identify the response.
62
+ * _neb-reply-id_ may be set on a request to an arbitrary string to help you identify the response.
72
63
 
73
- * _neb-in-reply-to_ is set on a response and contains the nebulous-reply-id
74
- of the request.
64
+ * _neb-in-reply-to_ is set on a response and contains the neb-reply-id of the request. (see rule 4.)
75
65
 
76
66
  ### Message Body ###
77
67
 
78
- The Protocol specifies a format for the message body. It consists of three
79
- fields:
68
+ The Protocol specifies a format for the message body. It consists of three fields:
80
69
 
81
- * _verb_ is the keyword that tells the receiving system how to process the
82
- message.
70
+ * _verb_ is the keyword that tells the receiving system how to process the message.
83
71
 
84
- * _parameters_ is an arbitrary field that is context-dependant on verb. The
85
- routine that handles the verb is expected to be able to parse it. It is
86
- optional.
72
+ * _parameters_ is an arbitrary field that is context-dependant on verb. The routine that handles
73
+ the verb is expected to be able to parse it. It is optional.
87
74
 
88
75
  * _description_ is a text field and can contain anything. It is optional.
89
76
 
90
- Nebulous supports message bodies in either JSON (in which case parameters is an
91
- array) or plain text (in which case it expects to find the fields formatted in
92
- the same way as STOMP headers: seperated by line breaks, where each line
93
- consists of the field name, a colon, and the value).
77
+ Nebulous supports message bodies in either JSON (in which case parameters is probably an array) or
78
+ plain text (in which case it expects to find the fields formatted in the same way as STOMP headers:
79
+ seperated by line breaks, where each line consists of the field name, a colon, and the value).
94
80
 
95
81
  There are a couple of special verbs:
96
82
 
97
- * _success_ as a verb in a response is used when no information needs to be
98
- returned except that the request operation went ahead without problem.
83
+ * _success_ as a verb in a response is used when no information needs to be returned except that
84
+ the request operation went ahead without problem.
99
85
 
100
- * _error_ as a verb is used when the requested operation failed. The
101
- expectation is that you will put an error message in the description field;
102
- you can use parameters as you see fit, of course.
86
+ * _error_ as a verb is used when the requested operation failed. The expectation is that you will
87
+ put an error message in the description field; you can use parameters as you see fit, of course.
103
88
 
104
89
 
105
90
  Notes on usage
106
91
  --------------
107
- There are two use cases here. The first (let's call it _Q & A_) is when a
108
- process needs information and sends a request, then waits for a response. The
109
- second (let's call it _Responder_) is at the other end of that process; it
110
- camps onto one or more queues waiting for requests, and arranges for responses
111
- to be sent.
92
+
93
+ There are two use cases here. The first (let's call it _Q & A_) is when a process needs information
94
+ and sends a request, then waits for a response. The second (let's call it _Responder_) is at the
95
+ other end of that process; it camps onto one or more queues waiting for requests, and arranges for
96
+ responses to be sent.
112
97
 
113
98
  ### Responder ###
114
99
 
115
- Let's talk about the Responder use case first, since it's simpler; we've
116
- basically been talking about it for the whole of this document. You'll need to
117
- designate a queue for incoming requests on any given system. You might want
118
- more than one; in ABL, where traffic jams are likely because I can't just
119
- spawn up a thread to handle each incoming message, my current thinking is to
120
- have two incoming queues, one for reqests that take a few seconds, and another
121
- for requests that take longer.
122
-
123
- Remember that rule 6 says that any messages that go to a queue like this will
124
- be consumed without concern for whether the message will make sense to the
125
- system in question; this is basically there so that the ABL code can split up
126
- the process of grabbing new messages from the process of working out what they
127
- are and how to answer them.
128
-
129
- But the simplicity is appealing, regardless: post to this queue and the
130
- Responder that looks after this system will process it. Rule 1 guarantees
131
- you an answer so long as the system is up, so if you don't get one then either
132
- the target system is down or it's too busy to respond.
133
-
134
- The expectation is that the Responder system should use the verb of the message
135
- to control how it is dealt with. The parameters field is verb-specific; the
136
- combination of verb, expected parameters, and the nature of the returned
137
- message form a sort of contract, ie "verb x always expects parameters like
138
- this, and always behaves like that in response". This is partly implied by Rule
139
- 2, I think.
100
+ Let's talk about the Responder use case first, since it's simpler; we've basically been talking
101
+ about it for the whole of this document. You'll need to designate a queue for incoming requests on
102
+ any given system. You might want more than one; in ABL, where traffic jams are likely because I
103
+ can't just spawn up a thread to handle each incoming message, my current thinking is to have two
104
+ incoming queues, one for reqests that take a few seconds, and another for requests that take
105
+ longer.
106
+
107
+ Remember that rule 6 says that any messages that go to a queue like this will be consumed without
108
+ concern for whether the message will make sense to the system in question; this is basically there
109
+ so that the ABL code can split up the process of grabbing new messages from the process of working
110
+ out what they are and how to answer them.
111
+
112
+ But the simplicity is appealing, regardless: post to this queue and the Responder that looks after
113
+ this system will process it. Rule 1 guarantees you an answer so long as the system is up, so if you
114
+ don't get one then either the target system is down or it's too busy to respond.
115
+
116
+ The expectation is that the Responder system should use the verb of the message to control how it
117
+ is dealt with. The parameters field is verb-specific; the combination of verb, expected parameters,
118
+ and the nature of the returned message form a sort of contract, ie "verb x always expects
119
+ parameters like this, and always behaves like that in response". This is partly implied by Rule 2,
120
+ I think.
140
121
 
141
122
  ### Q & A ###
142
123
 
143
- The Q & A use case is more interesting since it's what the whole thing is for,
144
- but some of it really falls outside of The Protocol.
145
-
146
- In theory, Rule 3 says you can fail to use _neb-reply-to_ and pick up your
147
- response from the same queue you posted the message to. But rule 6 says that if
148
- you do that you don't have any guarantee at all of getting your message; the
149
- Responder will take it. So for practical purposes you almost always *have* to
150
- set a reply-to queue in your request.
151
-
152
- Likewise, Rule 4 says that _neb-reply-id_ is optional. But in practice you
153
- should almost certainly set it. Yes, you can specify a brand new queue that is
154
- unique to your request -- or probably unique, anyway -- but it turns out that
155
- some message servers, our RabbitMQ included, don't let you subscribe to a queue
156
- that doesn't exist. It's easy enough to create a queue: you just send a message
157
- to it. But now there are two messages in that queue (or more if turns out that
158
- you've got some queue namespace collision after all) and you have to pick your
159
- response from it, and the easiest way is to set a reply id.
160
-
161
- So let's assume a median worst case: you're posting a request to a Responder
162
- queue with a reply-id set to something hopefully unique, and reply-to set to a
163
- common queue that many processes use to pick up replies. There are two
164
- challenges here: first, working out which message is yours; second, avoiding
165
- consuming those messages that are not.
166
-
167
- For a unique reply-id you could do worse than starting with the session ID that
168
- STOMP returns when you send a CONNECT frame; clearly the message server thinks
169
- that is unique, and it should know. In the Ruby Stomp gem, you can get it with
170
- `client.connection_frame().headers["session"]` where client is your
171
- `Stomp::Client` instance; in my ABL jhstomp.p library call `get_session_id()`.
172
-
173
- Now that you have a good reply ID you can tell which is yours by Rule 4; just
174
- test the _neb-in-reply-to_ header of each message.
175
-
176
- The second problem, of avoiding consuming messages that don't match your
177
- reply-id, is handled by careful use of STOMP. If when subscribing you set the
178
- header `ack:client-individual`, then you must manually acknowledge each message
179
- you want to consume with an ACK frame.
180
-
181
- Finally, you get to handle the response. Rule 1 says that it will either be an
182
- error verb, a success verb ... or something else specific to the verb. The
183
- nature of messages in responses is really outside of The Protocol; you are free
184
- to use the verb / parameters / description format if you wish. Again, I'm
185
- assuming that a given verb will always require the same parameters and return
186
- the same message. I think that to do otherwise would be very confusing. But The
187
- Protocol can't enforce that.
188
-
189
- Note also that while The Protocol says that a request should always result in a
190
- response, there is nothing to say that the sender of the request should care --
191
- say, in the example of a request that results in a report being emailed, which
192
- takes 20 minutes.
124
+ The Q & A use case is more interesting since it's what the whole thing is for, but some of it
125
+ really falls outside of The Protocol.
126
+
127
+ In theory, Rule 3 says you can fail to use _neb-reply-to_ and pick up your response from the same
128
+ queue you posted the message to. But rule 6 says that if you do that you don't have any guarantee
129
+ at all of getting your message; the Responder will take it. So for practical purposes you almost
130
+ always *have* to set a reply-to queue in your request.
131
+
132
+ Likewise, Rule 4 says that _neb-reply-id_ is optional. But in practice you should almost certainly
133
+ set it. Yes, you can specify a brand new queue that is unique to your request -- or probably
134
+ unique, anyway -- but it turns out that some message servers, our RabbitMQ included, don't let you
135
+ subscribe to a queue that doesn't exist. It's easy enough to create a queue: you just send a
136
+ message to it. But now there are two messages in that queue (or more if turns out that you've got
137
+ some queue namespace collision after all) and you have to pick your response from it, and the
138
+ easiest way is to set a reply id.
139
+
140
+ So let's assume a median worst case: you're posting a request to a Responder queue with a reply-id
141
+ set to something hopefully unique, and reply-to set to a common queue that many processes use to
142
+ pick up replies. There are two challenges here: first, working out which message is yours; second,
143
+ avoiding consuming those messages that are not.
144
+
145
+ For a unique reply-id you could do worse than starting with the session ID that STOMP returns when
146
+ you send a CONNECT frame; clearly the message server thinks that is unique, and it should know. In
147
+ the Ruby Stomp gem, you can get it with `client.connection_frame().headers["session"]` where client
148
+ is your `Stomp::Client` instance; in my ABL jhstomp.p library call `get_session_id()`.
149
+
150
+ Now that you have a good reply ID you can tell which is yours by Rule 4; just test the
151
+ _neb-in-reply-to_ header of each message.
152
+
153
+ The second problem, of avoiding consuming messages that don't match your reply-id, is handled by
154
+ careful use of STOMP. If when subscribing you set the header `ack:client-individual`, then you must
155
+ manually acknowledge each message you want to consume with an ACK frame.
156
+
157
+ Finally, you get to handle the response. Rule 1 says that it will either be an error verb, a
158
+ success verb ... or something else specific to the verb. The nature of messages in responses is
159
+ really outside of The Protocol; you are free to use the verb / parameters / description format if
160
+ you wish. Again, I'm assuming that a given verb will always require the same parameters and return
161
+ the same message. I think that to do otherwise would be very confusing. But The Protocol can't
162
+ enforce that.
163
+
164
+ Note also that while The Protocol says that a request should always result in a response, there is
165
+ nothing to say that the sender of the request should care -- say, in the example of a request that
166
+ results in a report being emailed, which takes 20 minutes.
193
167
 
@@ -14,9 +14,9 @@ describe NebRequestNull do
14
14
 
15
15
  def disable(thing)
16
16
  NebulousStomp.init( :stompConnectHash => thing == :stomp ? {} : stomp_hash,
17
- :redisConnectHash => thing == :redis ? {} : redis_hash,
18
- :messageTimeout => 5,
19
- :cacheTimeout => 20 )
17
+ :redisConnectHash => thing == :redis ? {} : redis_hash,
18
+ :messageTimeout => 5,
19
+ :cacheTimeout => 20 )
20
20
 
21
21
  NebulousStomp.add_target( :accord,
22
22
  :sendQueue => "/queue/laplace.dev",
@@ -36,6 +36,7 @@ describe NebRequestNull do
36
36
 
37
37
  let(:redis_hash) { {host: '127.0.0.1', port: 6379, db: 0} }
38
38
 
39
+
39
40
  before do
40
41
  disable(:nothing)
41
42
  end
@@ -95,7 +96,7 @@ describe NebRequestNull do
95
96
 
96
97
  it "returns something from STOMP" do
97
98
  req = new_request('accord', 'foo')
98
- req.insert_fake_stomp( Message.from_parts('', '', 'foo', 'bar', 'baz') )
99
+ req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
99
100
  response = req.send_no_cache
100
101
 
101
102
  expect( response ).to be_a NebulousStomp::Message
@@ -124,7 +125,7 @@ describe NebRequestNull do
124
125
 
125
126
  it "returns a Message object from STOMP the first time" do
126
127
  req = new_request('accord', 'foo')
127
- req.insert_fake_stomp( Message.from_parts('', '', 'foo', 'bar', 'baz') )
128
+ req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
128
129
 
129
130
  response = req.send
130
131
  expect( response ).to be_a NebulousStomp::Message
@@ -133,7 +134,7 @@ describe NebRequestNull do
133
134
 
134
135
  it "returns the answer from the cache if there is one" do
135
136
  req = new_request('accord', 'foo')
136
- req.insert_fake_stomp( Message.from_parts('', '', 'foo', 'bar', 'baz') )
137
+ req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
137
138
  req.insert_fake_redis('xxx', {'verb' => 'frog'}.to_json)
138
139
  response = req.send
139
140
 
@@ -143,14 +144,14 @@ describe NebRequestNull do
143
144
 
144
145
  it "allows you to specify a message timeout" do
145
146
  req = new_request('accord', 'foo')
146
- req.insert_fake_stomp( Message.from_parts('', '', 'foo', 'bar', 'baz') )
147
+ req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
147
148
 
148
149
  expect{ req.send(3) }.not_to raise_exception
149
150
  end
150
151
 
151
152
  it "allows you to specify a message timeout & cache timeout" do
152
153
  req = new_request('accord', 'foo')
153
- req.insert_fake_stomp( Message.from_parts('', '', 'foo', 'bar', 'baz') )
154
+ req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
154
155
 
155
156
  expect{ req.send(3, 120) }.not_to raise_exception
156
157
  end
@@ -163,7 +164,7 @@ describe NebRequestNull do
163
164
  it 'still works if Redis is turned off in the config' do
164
165
  disable(:redis)
165
166
  r = new_request('accord', 'tom')
166
- r.insert_fake_stomp( Message.from_parts('', '', 'foo', 'bar', 'baz') )
167
+ r.insert_fake_stomp( Message.from_parts(nil, r.replyID, 'foo', 'bar', 'baz') )
167
168
 
168
169
  response = r.send
169
170
  expect( response ).to be_a NebulousStomp::Message
@@ -104,8 +104,8 @@ describe NebRequest do
104
104
  describe "#send_no_cache" do
105
105
 
106
106
  it "returns something from STOMP" do
107
- stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
108
107
  request = new_request('accord', 'foo')
108
+ stomp_h.insert_fake( Message.from_parts(nil, request.replyID, 'foo', 'bar', 'baz') )
109
109
  response = request.send_no_cache
110
110
 
111
111
  expect( response ).to be_a NebulousStomp::Message
@@ -133,8 +133,8 @@ describe NebRequest do
133
133
  describe "#send" do
134
134
 
135
135
  it "returns a Message object from STOMP the first time" do
136
- stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
137
136
  request = new_request('accord', 'foo')
137
+ stomp_h.insert_fake( Message.from_parts(nil, request.replyID, 'foo', 'bar', 'baz') )
138
138
 
139
139
  response = request.send
140
140
  expect( response ).to be_a NebulousStomp::Message
@@ -142,7 +142,7 @@ describe NebRequest do
142
142
  end
143
143
 
144
144
  it "returns the answer from the cache the second time" do
145
- stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
145
+ stomp_h.insert_fake( Message.from_parts(nil, nil, 'foo', 'bar', 'baz') )
146
146
  redis_h.insert_fake('xxx', {'verb' => 'frog'}.to_json)
147
147
 
148
148
  # First time
@@ -158,15 +158,15 @@ describe NebRequest do
158
158
  end
159
159
 
160
160
  it "allows you to specify a message timeout" do
161
- stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
162
161
  request = new_request('accord', 'foo')
162
+ stomp_h.insert_fake( Message.from_parts(nil, request.replyID, 'foo', 'bar', 'baz') )
163
163
 
164
164
  expect{ request.send(3) }.not_to raise_exception
165
165
  end
166
166
 
167
167
  it "allows you to specify a message timeout & cache timeout" do
168
- stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
169
168
  request = new_request('accord', 'foo')
169
+ stomp_h.insert_fake( Message.from_parts(nil, request.replyID, 'foo', 'bar', 'baz') )
170
170
 
171
171
  expect{ request.send(3, 120) }.not_to raise_exception
172
172
  end
@@ -178,8 +178,8 @@ describe NebRequest do
178
178
 
179
179
  it 'still works if Redis is turned off in the config' do
180
180
  rh = RedisHandlerNull.new({})
181
- stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
182
181
  r = NebRequest.new('accord', 'tom', nil, nil, stomp_h, rh)
182
+ stomp_h.insert_fake( Message.from_parts(nil, r.replyID, 'foo', 'bar', 'baz') )
183
183
 
184
184
  response = r.send
185
185
  expect( response ).to be_a NebulousStomp::Message
@@ -158,7 +158,6 @@ describe StompHandler do
158
158
 
159
159
  it "takes an initialization hash" do
160
160
  expect{ StompHandler.new(foo: 'bar') }.not_to raise_exception
161
- expect{ StompHandler.new }.to raise_exception ArgumentError
162
161
  end
163
162
 
164
163
  end
@@ -6,8 +6,9 @@ require 'nebulous_stomp'
6
6
  # It's really only here to double check that the Stomp gem hasn't moved the
7
7
  # goalposts (again).
8
8
  #
9
- # In order for it to work, the JH RabbitMQ server has to be where we left it.
10
- # So this test won't work for you out of the box, unless you are me.
9
+ # In order for it to work, the JH RabbitMQ server has to be where we left it. And you need a
10
+ # responder listening to /queue/nebulout.test for the 'ping' verb. So this test won't work for you
11
+ # out of the box, unless you are me.
11
12
  #
12
13
  describe 'through test' do
13
14
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nebulous_stomp
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Jones
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-21 00:00:00.000000000 Z
11
+ date: 2016-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler