georgi-nsq-ruby 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: '0592446085ea7e5ee98b2823b84159594c70802d'
4
+ data.tar.gz: 4f64b4526e26ed2cb194222b9b6046a3063bb366
5
+ SHA512:
6
+ metadata.gz: f689bef377f060f4b9407750a05be8385df077baf064f2be8e650e955217ed84f7a4427d34126b2f4a31a489cf23fca8f853f0dcd7461eabcb003f34f13bcb53
7
+ data.tar.gz: 93b240b8475c2bed9312371b3ecc85e98d1c36f017c31e2200ab6d8005d5a65190ab93ff2ccec1822e879591b5b4a20342d5940d68d69bc0834dd64c1f0f7b73
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Wistia, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,405 @@
1
+ # nsq-ruby
2
+
3
+ nsq-ruby is a simple NSQ client library written in Ruby.
4
+
5
+ - The code is straightforward.
6
+ - It has no dependencies.
7
+ - It's well tested.
8
+ - It's being used in production and has processed billions of messages.
9
+
10
+ [![Build Status](https://travis-ci.org/wistia/nsq-ruby.svg?branch=master)](https://travis-ci.org/wistia/nsq-ruby)
11
+
12
+
13
+ ## Quick start
14
+
15
+ ### Publish messages
16
+
17
+ ```Ruby
18
+ require 'nsq'
19
+ producer = Nsq::Producer.new(
20
+ nsqd: '127.0.0.1:4150',
21
+ topic: 'some-topic'
22
+ )
23
+
24
+ # Write a message to NSQ
25
+ producer.write('some-message')
26
+
27
+ # Write a bunch of messages to NSQ (uses mpub)
28
+ producer.write('one', 'two', 'three', 'four', 'five')
29
+
30
+ # Write a deferred message to NSQ (uses dpub)
31
+
32
+ # Message deferred of 10s
33
+ producer.deferred_write(10, 'one')
34
+
35
+ # Message deferred of 1250ms
36
+ producer.deferred_write(1.25, 'one')
37
+
38
+ # Close the connection
39
+ producer.terminate
40
+ ```
41
+
42
+ ### Consume messages
43
+
44
+ ```Ruby
45
+ require 'nsq'
46
+ consumer = Nsq::Consumer.new(
47
+ nsqlookupd: '127.0.0.1:4161',
48
+ topic: 'some-topic',
49
+ channel: 'some-channel'
50
+ )
51
+
52
+ # Pop a message off the queue
53
+ msg = consumer.pop
54
+ puts msg.body
55
+ msg.finish
56
+
57
+ # Close the connections
58
+ consumer.terminate
59
+ ```
60
+
61
+
62
+ ## Producer
63
+
64
+ ### Initialization
65
+
66
+ The Nsq::Producer constructor takes the following options:
67
+
68
+ | Option | Description | Default |
69
+ |---------------|----------------------------------------|--------------------|
70
+ | `topic` | Topic to which to publish messages | |
71
+ | `nsqd` | Host and port of the nsqd instance | '127.0.0.1:4150' |
72
+ | `nsqlookupd` | Use lookupd to auto discover nsqds | |
73
+ | `tls_v1` | Flag for tls v1 connections | false |
74
+ | `tls_options` | Optional keys+certs for TLS connections| |
75
+
76
+ For example, if you'd like to publish messages to a single nsqd.
77
+
78
+ ```Ruby
79
+ producer = Nsq::Producer.new(
80
+ nsqd: '6.7.8.9:4150',
81
+ topic: 'topic-of-great-esteem'
82
+ )
83
+ ```
84
+
85
+ Alternatively, you can use nsqlookupd to find all nsqd nodes in the cluster.
86
+ When you instantiate Nsq::Producer in this way, it will automatically maintain
87
+ connections to all nsqd instances. When you publish a message, it will be sent
88
+ to a random nsqd instance.
89
+
90
+ ```Ruby
91
+ producer = Nsq::Producer.new(
92
+ nsqlookupd: ['1.2.3.4:4161', '6.7.8.9:4161'],
93
+ topic: 'topic-of-great-esteem'
94
+ )
95
+ ```
96
+
97
+ If you need to connect using SSL/TLS Authentication via `tls_options`
98
+
99
+ ```Ruby
100
+ producer = Nsq::Producer.new(
101
+ nsqlookupd: ['1.2.3.4:4161', '6.7.8.9:4161'],
102
+ topic: 'topic-of-great-esteem',
103
+ tls_v1: true,
104
+ tls_options: {
105
+ key: '/path/to/ssl/key.pem',
106
+ certificate: '/path/to/ssl/certificate.pem',
107
+ ca_certificate: '/path/to/ssl/ca_certificate.pem',
108
+ verify_mode: OpenSSL::SSL::VERIFY_PEER
109
+ }
110
+ )
111
+ ```
112
+
113
+ If you need to connect using simple `tls_v1`
114
+
115
+ ```Ruby
116
+ producer = Nsq::Producer.new(
117
+ nsqlookupd: ['1.2.3.4:4161', '6.7.8.9:4161'],
118
+ topic: 'topic-of-great-esteem',
119
+ tls_v1: true
120
+ )
121
+ ```
122
+
123
+ ### `#write`
124
+
125
+ Publishes one or more messages to nsqd. If you give it a single argument, it will
126
+ send it to nsqd via `PUB`. If you give it multiple arguments, it will send all
127
+ those messages to nsqd via `MPUB`. It will automatically call `to_s` on any
128
+ arguments you give it.
129
+
130
+ ```Ruby
131
+ # Send a single message via PUB
132
+ producer.write(123)
133
+
134
+ # Send three messages via MPUB
135
+ producer.write(456, 'another-message', { key: 'value' }.to_json)
136
+ ```
137
+
138
+ If its connection to nsqd fails, it will automatically try to reconnect with
139
+ exponential backoff. Any messages that were sent to `#write` will be queued
140
+ and transmitted after reconnecting.
141
+
142
+ **Note** we don't wait for nsqd to acknowledge our writes. As a result, if the
143
+ connection to nsqd fails, you can lose messages. This is acceptable for our use
144
+ cases, mostly because we are sending messages to a local nsqd instance and
145
+ failure is very rare.
146
+
147
+
148
+ ### `#write_to_topic`
149
+
150
+ Publishes one or more messages to nsqd. Like `#write`, but allows you to specify
151
+ the topic. Use this method if you want a single producer instance to write to
152
+ multiple topics.
153
+
154
+ ```Ruby
155
+ # Send a single message via PUB to the topic 'rutabega'
156
+ producer.write_to_topic('rutabega', 123)
157
+
158
+ # Send multiple messages via MPUB to the topic 'kohlrabi'
159
+ producer.write_to_topic('kohlrabi', 'a', 'b', 'c')
160
+ ```
161
+
162
+
163
+ ### `#connected?`
164
+
165
+ Returns true if it's currently connected to nsqd and false if not.
166
+
167
+ ### `#terminate`
168
+
169
+ Closes the connection to nsqd and stops it from trying to automatically
170
+ reconnect.
171
+
172
+ This is automatically called `at_exit`, but it's good practice to close your
173
+ producers when you're done with them.
174
+
175
+
176
+ ## Consumer
177
+
178
+ ### Initialization
179
+
180
+ | Option | Description | Default |
181
+ |----------------------|-----------------------------------------------|--------------------|
182
+ | `topic` | Topic to consume messages from | |
183
+ | `channel` | Channel name for this consumer | |
184
+ | `nsqlookupd` | Use lookupd to automatically discover nsqds | |
185
+ | `nsqd` | Connect directly to a single nsqd instance | '127.0.0.1:4150' |
186
+ | `max_in_flight` | Max number of messages for this consumer to have in flight at a time | 1 |
187
+ | `discovery_interval` | Seconds between queue discovery via nsqlookupd | 60.0 |
188
+ | `msg_timeout` | Milliseconds before nsqd will timeout a message | 60000 |
189
+ | `tls_v1` | Flag for tls v1 connections | false |
190
+ | `tls_options` | Optional keys and certificates for TLS connections | |
191
+
192
+
193
+ For example:
194
+
195
+ ```Ruby
196
+ consumer = Nsq::Consumer.new(
197
+ topic: 'the-topic',
198
+ channel: 'my-channel',
199
+ nsqlookupd: ['127.0.0.1:4161', '4.5.6.7:4161'],
200
+ max_in_flight: 100,
201
+ discovery_interval: 30,
202
+ msg_timeout: 120_000,
203
+ tls_v1: true,
204
+ tls_options: {
205
+ key: '/path/to/ssl/key.pem',
206
+ certificate: '/path/to/ssl/certificate.pem',
207
+ ca_certificate: '/path/to/ssl/ca_certificate.pem',
208
+ verify_mode: OpenSSL::SSL::VERIFY_PEER
209
+ }
210
+ )
211
+ ```
212
+
213
+ Notes:
214
+
215
+ - `nsqlookupd` can be a string or array of strings for each nsqlookupd service
216
+ you'd like to use. The format is `"<host>:<http-port>"`. If you specify
217
+ `nsqlookupd`, it ignores the `nsqd` option.
218
+ - `max_in_flight` is for the total max in flight across all the connections,
219
+ but to make the implementation of `nsq-ruby` as simple as possible, the minimum
220
+ `max_in_flight` _per_ connection is 1. So if you set `max_in_flight` to 1 and
221
+ are connected to 3 nsqds, you may have up to 3 messages in flight at a time.
222
+
223
+
224
+ ### `#pop`
225
+
226
+ `nsq-ruby` works by maintaining a local queue of in flight messages from NSQ.
227
+ To get at these messages, just call pop.
228
+
229
+ ```Ruby
230
+ message = consumer.pop
231
+ ```
232
+
233
+ If there are messages on the queue, `pop` will return one immediately. If there
234
+ are no messages on the queue, `pop` will block execution until one arrives.
235
+
236
+ Be aware, while `#pop` is blocking, your process will be unresponsive. This
237
+ can be a problem in certain cases, like if you're trying to gracefully restart
238
+ a worker process by sending it a `TERM` signal. See `#pop_without_blocking` for
239
+ information on how to mitigate this issue.
240
+
241
+
242
+ ### `#pop_without_blocking`
243
+
244
+ This is just like `#pop` except it doesn't block. It always returns immediately.
245
+ If there are no messages in the queue, it will return `nil`.
246
+
247
+ If you're consuming from a low-volume topic and don't want to get stuck in a
248
+ blocking state, you can use this method to consume messages like so:
249
+
250
+ ```Ruby
251
+ loop do
252
+ if msg = @messages.pop_without_blocking
253
+ # do something
254
+ msg.finish
255
+ else
256
+ # wait for a bit before checking for new messages
257
+ sleep 0.01
258
+ end
259
+ end
260
+ ```
261
+
262
+
263
+ ### `#size`
264
+
265
+ `size` returns the size of the local message queue.
266
+
267
+
268
+ ### `#terminate`
269
+
270
+ Gracefully closes all connections and stops the consumer. You should call this
271
+ when you're finished with a consumer object.
272
+
273
+
274
+ ## Message
275
+
276
+ The `Message` object is what you get when you call `pop` on a consumer.
277
+ Once you have a message, you'll likely want to get its contents using the `#body`
278
+ method, and then call `#finish` once you're done with it.
279
+
280
+ ### `body`
281
+
282
+ Returns the body of the message as a UTF-8 encoded string.
283
+
284
+ ### `attempts`
285
+
286
+ Returns the number of times this message was attempted to be processed. For
287
+ most messages this should be 1 (since it will be your first attempt processing
288
+ them). If it's more than 1, that means that you requeued the message or it
289
+ timed out in flight.
290
+
291
+ ### `timestamp`
292
+
293
+ Returns the time this message was originally sent to NSQ as a `Time` object.
294
+
295
+ ### `#finish`
296
+
297
+ Notify NSQ that you've completed processing of this message.
298
+
299
+ ### `#touch`
300
+
301
+ Tells NSQ to reset the message timeout for this message so you have more time
302
+ to process it.
303
+
304
+ ### `#requeue(timeout = 0)`
305
+
306
+ Tells NSQ to requeue this message. Called with no arguments, this will requeue
307
+ the message and it will be available to be received immediately.
308
+
309
+ Optionally you can pass a number of milliseconds as an argument. This tells
310
+ NSQ to delay its requeueing by that number of milliseconds.
311
+
312
+
313
+ ## Logging
314
+
315
+ By default, `nsq-ruby` doesn't log anything. To enable logging, use
316
+ `Nsq.logger=` and point it at a Ruby Logger instance. Like this:
317
+
318
+ ```Ruby
319
+ Nsq.logger = Logger.new(STDOUT)
320
+ ```
321
+
322
+
323
+ ## Requirements
324
+
325
+ NSQ v0.2.29 or later for IDENTIFY metadata specification (0.2.28) and per-
326
+ connection timeout support (0.2.29).
327
+
328
+
329
+ ### Supports
330
+
331
+ - Discovery via nsqlookupd
332
+ - Automatic reconnection to nsqd
333
+ - Producing to all nsqd instances automatically via nsqlookupd
334
+ - TLS
335
+
336
+
337
+ ### Does not support
338
+
339
+ - Compression
340
+ - Backoff
341
+
342
+ If you need more advanced features, like these, you should check out
343
+ [Krakow](https://github.com/chrisroberts/krakow), a more fully featured NSQ
344
+ client for Ruby.
345
+
346
+
347
+ ## Testing
348
+
349
+ Run the tests like this:
350
+
351
+ ```
352
+ rake spec
353
+ ```
354
+
355
+ Want a deluge of logging while running the specs to help determine what is
356
+ going on?
357
+
358
+ ```
359
+ VERBOSE=true rake spec
360
+ ```
361
+
362
+
363
+ ## Is this production ready?
364
+
365
+ Yes! It's used in several critical parts of our infrastructure at
366
+ [Wistia](http://wistia.com) and currently produces and consumes hundreds of
367
+ millions of messages a day.
368
+
369
+
370
+ ## Authors & Contributors
371
+
372
+ - Robby Grossman ([@freerobby](https://github.com/freerobby))
373
+ - Brendan Schwartz ([@bschwartz](https://github.com/bschwartz))
374
+ - Marshall Moutenot ([@mmoutenot](https://github.com/mmoutenot))
375
+ - Danielle Sucher ([@DanielleSucher](https://github.com/DanielleSucher))
376
+ - Anders Chen ([@chen-anders](https://github.com/chen-anders))
377
+ - Thomas O'Neil ([@alieander](https://github.com/alieander))
378
+ - Unbekandt Léo ([@soulou](https://github.com/Soulou))
379
+ - Matthias Schneider ([@mschneider82](https://github.com/mschneider82))
380
+ - Lukas Eklund ([@leklund](https://github.com/leklund))
381
+ - Paco Guzmán ([@pacoguzman](https://github.com/pacoguzman))
382
+
383
+
384
+ ## MIT License
385
+
386
+ Copyright (C) 2016 Wistia, Inc.
387
+
388
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
389
+ this software and associated documentation files (the "Software"), to deal in
390
+ the Software without restriction, including without limitation the rights to
391
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
392
+ of the Software, and to permit persons to whom the Software is furnished to do
393
+ so, subject to the following conditions:
394
+
395
+ The above copyright notice and this permission notice shall be included in all
396
+ copies or substantial portions of the Software.
397
+
398
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
399
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
400
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
401
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
402
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
403
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
404
+ SOFTWARE.
405
+
@@ -0,0 +1,13 @@
1
+ require_relative 'version'
2
+
3
+ require_relative 'nsq/logger'
4
+
5
+ require_relative 'nsq/exceptions'
6
+
7
+ require_relative 'nsq/frames/frame'
8
+ require_relative 'nsq/frames/error'
9
+ require_relative 'nsq/frames/response'
10
+ require_relative 'nsq/frames/message'
11
+
12
+ require_relative 'nsq/consumer'
13
+ require_relative 'nsq/producer'