fastly_nsq 0.13.2 → 1.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.
Files changed (68) hide show
  1. checksums.yaml +5 -5
  2. data/.env +4 -0
  3. data/.overcommit.yml +3 -3
  4. data/.rubocop.yml +11 -1
  5. data/.travis.yml +8 -1
  6. data/Gemfile +9 -0
  7. data/README.md +52 -82
  8. data/Rakefile +2 -0
  9. data/bin/fastly_nsq +1 -0
  10. data/docker-compose.yml +23 -0
  11. data/examples/.sample.env +0 -3
  12. data/fastly_nsq.gemspec +7 -8
  13. data/lib/fastly_nsq.rb +44 -50
  14. data/lib/fastly_nsq/cli.rb +20 -14
  15. data/lib/fastly_nsq/consumer.rb +26 -30
  16. data/lib/fastly_nsq/feeder.rb +16 -0
  17. data/lib/fastly_nsq/http/nsqd.rb +7 -1
  18. data/lib/fastly_nsq/http/nsqlookupd.rb +1 -1
  19. data/lib/fastly_nsq/launcher.rb +31 -23
  20. data/lib/fastly_nsq/listener.rb +34 -103
  21. data/lib/fastly_nsq/manager.rb +48 -72
  22. data/lib/fastly_nsq/message.rb +2 -0
  23. data/lib/fastly_nsq/messenger.rb +5 -5
  24. data/lib/fastly_nsq/priority_queue.rb +12 -0
  25. data/lib/fastly_nsq/priority_thread_pool.rb +32 -0
  26. data/lib/fastly_nsq/producer.rb +52 -32
  27. data/lib/fastly_nsq/testing.rb +239 -0
  28. data/lib/fastly_nsq/tls_options.rb +2 -0
  29. data/lib/fastly_nsq/version.rb +3 -1
  30. data/spec/{lib/fastly_nsq/cli_spec.rb → cli_spec.rb} +2 -0
  31. data/spec/consumer_spec.rb +59 -0
  32. data/spec/fastly_nsq_spec.rb +72 -0
  33. data/spec/feeder_spec.rb +22 -0
  34. data/spec/{lib/fastly_nsq/http → http}/nsqd_spec.rb +1 -1
  35. data/spec/{lib/fastly_nsq/http → http}/nsqlookupd_spec.rb +1 -1
  36. data/spec/{lib/fastly_nsq/http_spec.rb → http_spec.rb} +3 -1
  37. data/spec/integration_spec.rb +48 -0
  38. data/spec/launcher_spec.rb +50 -0
  39. data/spec/listener_spec.rb +184 -0
  40. data/spec/manager_spec.rb +111 -0
  41. data/spec/matchers/delegate.rb +32 -0
  42. data/spec/{lib/fastly_nsq/message_spec.rb → message_spec.rb} +2 -0
  43. data/spec/{lib/fastly_nsq/messenger_spec.rb → messenger_spec.rb} +7 -5
  44. data/spec/priority_thread_pool_spec.rb +19 -0
  45. data/spec/producer_spec.rb +94 -0
  46. data/spec/spec_helper.rb +32 -28
  47. data/spec/support/http.rb +37 -0
  48. data/spec/support/webmock.rb +22 -0
  49. data/spec/{lib/fastly_nsq/tls_options_spec.rb → tls_options_spec.rb} +2 -0
  50. metadata +54 -96
  51. data/env_configuration_for_local_gem_tests.yml +0 -5
  52. data/example_config_class.rb +0 -20
  53. data/examples/Rakefile +0 -41
  54. data/lib/fastly_nsq/fake_backend.rb +0 -114
  55. data/lib/fastly_nsq/listener/config.rb +0 -35
  56. data/lib/fastly_nsq/rake_task.rb +0 -78
  57. data/lib/fastly_nsq/strategy.rb +0 -36
  58. data/spec/lib/fastly_nsq/consumer_spec.rb +0 -72
  59. data/spec/lib/fastly_nsq/fake_backend_spec.rb +0 -135
  60. data/spec/lib/fastly_nsq/fastly_nsq_spec.rb +0 -10
  61. data/spec/lib/fastly_nsq/launcher_spec.rb +0 -56
  62. data/spec/lib/fastly_nsq/listener_spec.rb +0 -213
  63. data/spec/lib/fastly_nsq/manager_spec.rb +0 -127
  64. data/spec/lib/fastly_nsq/producer_spec.rb +0 -60
  65. data/spec/lib/fastly_nsq/rake_task_spec.rb +0 -142
  66. data/spec/lib/fastly_nsq/strategy_spec.rb +0 -36
  67. data/spec/lib/fastly_nsq_spec.rb +0 -18
  68. data/spec/support/env_helpers.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9e293af0d6cd86795807e1727fb3547085917dbf
4
- data.tar.gz: 08243ead04232661269fbb182be2087eaa0a6663
2
+ SHA256:
3
+ metadata.gz: d4e06ecec388c8a7d3f403fbb38ec03788522f25464a6b4a46815ccc584ba613
4
+ data.tar.gz: '04392e44b547924dfcba6df02b26ac86bc5580c32d30eb6b6ca8ecab313c39d0'
5
5
  SHA512:
6
- metadata.gz: a58cf76f4c36e5061080e65c819948ae78ca70595c01377ce4a2ba5745d45e28c7151c72dc23a0880832488ffae2cb0b681bd95a6fe16b1ea86a056cd0b34f5f
7
- data.tar.gz: 09915b030a22911a886b4f56ed345c6acd2d85b36f538626dc4e0133a998a77041b19ab6f820039bbbf94c6f2e5062466007c1647805099c7843c730aa7ff693
6
+ metadata.gz: de8962c909fd1cdd08c0182b4eac693c1d0dec1608c0c60826ace6232198d449e5780a2e4ca9f3aee9cdb0bbc6d73871fb25dabd8a419b62e9aaee65f4fbfdb9
7
+ data.tar.gz: b1bd13296fb6e13f285099374621c0af43485822b04eb3593ec5635f07fb6ff087aa304399b3f389de8b21ecba4304e16a38a716831cc084077fa29dcd5970ed
data/.env ADDED
@@ -0,0 +1,4 @@
1
+ NSQD_TCP_ADDRESS=127.0.0.1:4150
2
+ NSQD_HTTP_ADDRESS=127.0.0.1:4151
3
+ NSQLOOKUPD_TCP_ADDRESS=127.0.0.1:4160
4
+ NSQLOOKUPD_HTTP_ADDRESS=127.0.0.1:4161
data/.overcommit.yml CHANGED
@@ -27,8 +27,8 @@ CommitMsg:
27
27
  description: 'Prevent empty commit messages'
28
28
  enabled: true
29
29
  TextWidth:
30
- description: 'Ensure commit message subjects are <60 chars'
30
+ description: 'Ensure commit message subjects are <72 chars'
31
31
  enabled: true
32
32
  description: 'Checking text width'
33
- max_subject_width: 60
34
- max_body_width: 1000
33
+ max_subject_width: 72
34
+ max_body_width: 72
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ AllCops:
5
5
  - 'db/schema.rb'
6
6
  - 'vendor/**/*'
7
7
  - 'Gemfile'
8
- TargetRubyVersion: 2.2
8
+ TargetRubyVersion: 2.4
9
9
 
10
10
  Layout/DotPosition:
11
11
  Enabled: true
@@ -14,15 +14,25 @@ Layout/DotPosition:
14
14
  - leading
15
15
  - trailing
16
16
 
17
+ Lint/AmbiguousBlockAssociation:
18
+ Exclude:
19
+ - 'spec/**/*'
20
+
17
21
  Lint/RescueWithoutErrorClass:
18
22
  Enabled: false
19
23
 
20
24
  Metrics/MethodLength:
21
25
  Enabled: false
22
26
 
27
+ Metrics/AbcSize:
28
+ Enabled: false
29
+
23
30
  Metrics/LineLength:
24
31
  Enabled: false
25
32
 
33
+ Metrics/ParameterLists:
34
+ Enabled: false
35
+
26
36
  Metrics/BlockLength:
27
37
  ExcludedMethods: [describe, context, configure]
28
38
 
data/.travis.yml CHANGED
@@ -1,11 +1,18 @@
1
1
  language: ruby
2
2
  cache: bundler
3
+ sudo: false
3
4
  rvm:
4
- - 2.2.4
5
5
  - 2.3.5
6
6
  - 2.4.2
7
+ - 2.5.0
7
8
  script:
8
9
  - bundle exec rake
10
+ services:
11
+ - docker
12
+ before_install:
13
+ - docker-compose up -d
14
+ before_script:
15
+ - gem update --system
9
16
  notifications:
10
17
  slack:
11
18
  rooms:
data/Gemfile CHANGED
@@ -1,3 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
6
+
7
+ gem 'bundler-audit', '~> 0.5.0'
8
+ gem 'overcommit', '~> 0.32.0'
9
+ gem 'rake', '~> 11.1.2'
10
+ gem 'rdoc', '~> 4.2.2'
11
+ gem 'rubocop', '~> 0.51.0'
12
+ gem 'rubygems-tasks', '~> 0.2'
data/README.md CHANGED
@@ -61,15 +61,39 @@ producer.write(message_data.to_json)
61
61
  ```
62
62
  The mock/real strategy used
63
63
  can be switched
64
- by adding an environment variable
65
- to your application:
64
+ by requiring the test file and configuring the mode.
66
65
 
67
66
  ```ruby
68
- # for the fake
69
- ENV['FAKE_QUEUE'] = true
67
+ require 'fastly_nsq/testing'
68
+ FastlyNsq::Testing.enabled? #=> true
69
+ FastlyNsq::Testing.disabled? #=> false
70
70
 
71
- # for the real thing
72
- ENV['FAKE_QUEUE'] = false
71
+ producer = FastlyNsq::Producer.new(topic: topic)
72
+ listener = FastlyNsq::Listener.new(topic: topic, channel: channel, processor: ->(m) { puts 'got: '+ m.body })
73
+
74
+ FastlyNsq::Testing.fake! # default, messages accumulate on the listeners
75
+
76
+ producer.write '{"foo":"bar"}'
77
+ listener.messages.size #=> 1
78
+
79
+ FastlyNsq::Testing.reset! # remove all accumulated messages
80
+
81
+ listener.messages.size #=> 0
82
+
83
+ producer.write '{"foo":"bar"}'
84
+ listener.messages.size #=> 1
85
+
86
+ listener.drain
87
+ # got: {"foo"=>"bar"}
88
+ listener.messages.size #=> 0
89
+
90
+ FastlyNsq::Testing.inline! # messages are processed as they are produced
91
+ producer.write '{"foo":"bar"}'
92
+ # got: {"foo"=>"bar"}
93
+ listener.messages.size #=> 0
94
+
95
+ FastlyNsq::Testing.disable! # do it live
96
+ FastlyNsq::Testing.enable! # re-enable testing mode
73
97
  ```
74
98
 
75
99
  ### `FastlyNsq::Consumer`
@@ -93,11 +117,6 @@ consumer.size #=> 0
93
117
  consumer.terminate
94
118
  ```
95
119
 
96
- As above,
97
- the mock/real strategy used
98
- can be switched by setting the
99
- `FAKE_QUEUE` environment variable appropriately.
100
-
101
120
  ### `FastlyNsq::Listener`
102
121
 
103
122
  To process the next message on the queue:
@@ -107,70 +126,49 @@ topic = 'user_created'
107
126
  channel = 'my_consuming_service'
108
127
  processor = MessageProcessor
109
128
 
110
- FastlyNsq::Listener.new(topic: topic, channel: channel, processor: processor).go(run_once: true)
129
+ FastlyNsq::Listener.new(topic: topic, channel: channel, processor: processor)
111
130
  ```
112
131
 
113
- This will pop the next message
132
+ This will send messages through `FastlyNsq.manager.pool`
114
133
  off of the queue
115
134
  and send the JSON text body
116
- to `MessageProcessor.process(message_body, topic)`.
135
+ to `MessageProcessor.call(message)`.
117
136
 
118
- To initiate a blocking loop to process messages continuously:
137
+ Specify a topic priority by providing a number (default is 0)
119
138
 
120
139
  ```ruby
121
140
  topic = 'user_created'
122
141
  channel = 'my_consuming_service'
123
142
  processor = MessageProcessor
143
+ priority = 1 # a little higher
124
144
 
125
- FastlyNsq::Listener.new(topic: topic, channel: channel, processor: processor).go
145
+ FastlyNsq::Listener.new(topic: topic, channel: channel, processor: processor, priority: priority)
126
146
  ```
127
147
 
128
- This will block until
129
- there is a new message on the queue,
130
- pop the next message
131
- off of the queue
132
- and send it to `MessageProcessor.process(message_body, topic)`.
133
-
134
- ### `FastlyNsq::RakeTask`
148
+ ### `FastlyNsq::CLI`
135
149
 
136
150
  To help facilitate running the `FastlyNsq::Listener` in a blocking fashion
137
- outside your application, a simple `RakeTask` is provided.
138
-
139
- The task will listen
140
- to all specified topics,
141
- each in a separate thread.
151
+ outside your application, a `CLI` and bin script [`fastly_nsq`](bin/fastly_nsq)
152
+ are provided.
142
153
 
143
- This task can be added into your `Rakefile` in one of two ways:
154
+ This can be setup ahead of time by calling `FastlyNsq.configure` and passing block.
144
155
 
145
- Using a block:
146
156
  ```ruby
147
- require 'fastly_nsq/rake_task'
148
-
149
- FastlyNsq::RakeTask.new(:listen_task) do |task|
150
- task.channel = 'some_channel'
151
- task.topics = {
152
- 'some_topic' => SomeMessageProcessor
153
- }
157
+ # config/fastly_nsq.rb
158
+ FastlyNsq.configure do |config|
159
+ config.channel = 'fnsq'
160
+ config.logger = Logger.new
161
+ config.preprocessor = ->(_) { FastlyNsq.logger.info 'PREPROCESSESES' }
162
+
163
+ lc.listen 'posts', ->(m) { puts "posts: #{m.body}" }
164
+ lc.listen 'blogs', ->(m) { puts "blogs: #{m.body}" }, priority: 3
154
165
  end
155
166
  ```
156
167
 
157
- The task can also define a `call`-able "preprocessor" (called before any `Processor.process`) and a custom `logger`.
158
-
159
- See the [`Rakefile`](examples/Rakefile) file
160
- for more detail.
161
-
162
- ### `FastlyNsq::CLI`
163
-
164
- To help facilitate running the `FastlyNsq::Listener` in a blocking fashion
165
- outside your application, a `CLI` and bin script [`fastly_nsq`](bin/fastly_nsq)
166
- are provided.
167
-
168
- This can be setup ahead of time by calling `FastlyNsq.configure` and passing
169
- block. An exmaple of this can be found here: [`Example Config`](exmaple_config_class.rb)
170
-
171
168
  An example of using the cli:
169
+
172
170
  ```bash
173
- ./bin/fastly_nsq -r ./example_config_class.rb -L ./test.log -P ./fastly_nsq.pid -v -d -t 4
171
+ ./bin/fastly_nsq -r config/fastly_nsq.rb -L ./test.log -P ./fastly_nsq.pid -v -d -t 4 -c 10
174
172
  ```
175
173
 
176
174
  ### `FastlyNsq::Messenger`
@@ -178,13 +176,13 @@ An example of using the cli:
178
176
  Wrapper around a producer for sending messages and persisting producer objects.
179
177
 
180
178
  ```ruby
181
- FastlyNsq::Messenger.deliver(message: msg, on_topic: 'my_topic', originating_service: 'my service')
179
+ FastlyNsq::Messenger.deliver(message: msg, topic: 'my_topic', originating_service: 'my service')
182
180
  ```
183
181
 
184
182
  You can also optionally pass custom metadata.
185
183
 
186
184
  ```ruby
187
- FastlyNsq::Messenger.deliver(message: msg, on_topic: 'my_topic', originating_service: 'my service', meta: { test: 'test' })
185
+ FastlyNsq::Messenger.deliver(message: msg, topic: 'my_topic', originating_service: 'my service', meta: { test: 'test' })
188
186
  ```
189
187
 
190
188
  This will use a FastlyNsq::Producer for the given topic or create on if it isn't
@@ -282,34 +280,6 @@ NSQLOOKUPD_HTTP_ADDRESS='127.0.0.1:4161, 10.1.1.101:4161'
282
280
  See the [`.sample.env`](examples/.sample.env) file
283
281
  for more detail.
284
282
 
285
- ### Testing Against the Fake
286
-
287
- In the gem's test suite,
288
- the fake message queue is used.
289
-
290
- If you would like to force
291
- use of the real NSQ adapter,
292
- ensure `FAKE_QUEUE` is set to `false`.
293
-
294
- When you are developing your application,
295
- it is recommended to
296
- start by using the fake queue:
297
-
298
- ```shell
299
- FAKE_QUEUE=true
300
- ```
301
-
302
- Also be sure call
303
- `FakeBackend.reset!`
304
- before each test in your app to ensure
305
- there are no leftover messages.
306
-
307
- Also note that during gem tests,
308
- we are aliasing `MessageProcessor` to `SampleMessageProcessor`.
309
- You can also refer to the latter
310
- as an example of how
311
- you might write your own processor.
312
-
313
283
  ## Contributors
314
284
 
315
285
  * Adarsh Pandit ([@adarsh](https://github.com/adarsh))
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
4
 
3
5
  begin
data/bin/fastly_nsq CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pry'
4
5
  require 'fastly_nsq/cli'
@@ -0,0 +1,23 @@
1
+ version: '3'
2
+ services:
3
+ nsqlookupd:
4
+ image: nsqio/nsq
5
+ command: /nsqlookupd
6
+ ports:
7
+ - "4160:4160"
8
+ - "4161:4161"
9
+ nsqd:
10
+ image: nsqio/nsq
11
+ command: /nsqd --lookupd-tcp-address=nsqlookupd:4160 --broadcast-address localhost
12
+ depends_on:
13
+ - nsqlookupd
14
+ ports:
15
+ - "4150:4150"
16
+ - "4151:4151"
17
+ nsqadmin:
18
+ image: nsqio/nsq
19
+ command: /nsqadmin --lookupd-http-address=nsqlookupd:4161
20
+ depends_on:
21
+ - nsqlookupd
22
+ ports:
23
+ - "4171:4171"
data/examples/.sample.env CHANGED
@@ -11,6 +11,3 @@ NSQD_HTTP_ADDRESS='127.0.0.1:4151'
11
11
  NSQLOOKUPD_TCP_ADDRESS='127.0.0.1:4160'
12
12
  ## NSQLOOKUPD_HTTP_ADDRESS can be a single address or a comma seperated list
13
13
  NSQLOOKUPD_HTTP_ADDRESS='127.0.0.1:4161, 10.0.0.101:4161'
14
-
15
- # Uncomment to test against a live queue
16
- #LIVE_QUEUE=true
data/fastly_nsq.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('../lib', __FILE__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'fastly_nsq/version'
@@ -20,16 +22,13 @@ Gem::Specification.new do |gem|
20
22
 
21
23
  gem.add_development_dependency 'awesome_print', '~> 1.6'
22
24
  gem.add_development_dependency 'bundler', '~> 1.12'
23
- gem.add_development_dependency 'bundler-audit', '~> 0.5.0'
24
25
  gem.add_development_dependency 'dotenv'
25
- gem.add_development_dependency 'overcommit', '~> 0.32.0'
26
26
  gem.add_development_dependency 'pry-byebug', '~> 3.3'
27
- gem.add_development_dependency 'rake', '~> 11.1.2'
28
- gem.add_development_dependency 'rdoc', '~> 4.2.2'
29
- gem.add_development_dependency 'rspec', '~> 3.4.0'
30
- gem.add_development_dependency 'rubocop', '~> 0.51.0'
31
- gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
32
- gem.add_development_dependency 'webmock'
27
+ gem.add_development_dependency 'rspec', '~> 3.4'
28
+ gem.add_development_dependency 'rspec-eventually', '0.2'
29
+ gem.add_development_dependency 'webmock', '~> 3.0'
33
30
 
31
+ gem.add_dependency 'concurrent-ruby', '~> 1.0'
34
32
  gem.add_dependency 'nsq-ruby', '~> 2.0', '>= 2.0.5'
33
+ gem.add_dependency 'priority_queue_cxx', '~> 0.3'
35
34
  end
data/lib/fastly_nsq.rb CHANGED
@@ -1,62 +1,56 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'nsq'
2
- require 'fastly_nsq/consumer'
3
- require 'fastly_nsq/fake_backend'
4
- require 'fastly_nsq/listener'
5
- require 'fastly_nsq/message'
6
- require 'fastly_nsq/messenger'
7
- require 'fastly_nsq/producer'
8
- require 'fastly_nsq/strategy'
9
- require 'fastly_nsq/tls_options'
10
- require 'fastly_nsq/version'
4
+ require 'concurrent'
5
+ require 'fc'
6
+ require 'set'
7
+ require 'logger'
8
+ require 'forwardable'
11
9
 
12
10
  module FastlyNsq
13
- module_function
11
+ NotConnectedError = Class.new(StandardError)
12
+ ConnectionFailed = Class.new(StandardError)
14
13
 
15
- @preprocessor = nil
14
+ class << self
15
+ attr_accessor :channel, :preprocessor
16
+ attr_writer :logger
16
17
 
17
- def channel=(channel)
18
- @channel ||= channel
19
- end
20
-
21
- def logger=(logger)
22
- strategy.logger = logger
23
- end
18
+ def listen(topic, processor, **options)
19
+ FastlyNsq::Listener.new(topic: topic, processor: processor, **options)
20
+ end
24
21
 
25
- def preprocessor=(preprocessor)
26
- @preprocessor ||= preprocessor
27
- end
22
+ def logger
23
+ @logger ||= Logger.new(nil)
24
+ end
28
25
 
29
- def channel
30
- @channel
31
- end
26
+ def configure
27
+ yield self
28
+ end
32
29
 
33
- def logger
34
- strategy.logger
35
- end
30
+ def manager
31
+ @manager ||= FastlyNsq::Manager.new
32
+ end
36
33
 
37
- def preprocessor
38
- @preprocessor
39
- end
34
+ def manager=(manager)
35
+ @manager&.transfer(manager)
36
+ @manager = manager
37
+ end
40
38
 
41
- def strategy
42
- Strategy.for_queue
43
- end
44
-
45
- def configure
46
- yield self
47
- end
48
-
49
- def topic_map
50
- @listener_config.topic_map
51
- end
52
-
53
- def listener_config
54
- @listener_config ||= FastlyNsq::Listener::Config.new
55
- yield @listener_config if block_given?
56
- @listener_config
57
- end
58
-
59
- def reset_config
60
- @listener_config = nil
39
+ def lookupd_http_addresses
40
+ ENV.fetch('NSQLOOKUPD_HTTP_ADDRESS').split(',').map(&:strip)
41
+ end
61
42
  end
62
43
  end
44
+
45
+ require 'fastly_nsq/consumer'
46
+ require 'fastly_nsq/feeder'
47
+ require 'fastly_nsq/launcher'
48
+ require 'fastly_nsq/listener'
49
+ require 'fastly_nsq/manager'
50
+ require 'fastly_nsq/message'
51
+ require 'fastly_nsq/messenger'
52
+ require 'fastly_nsq/priority_queue'
53
+ require 'fastly_nsq/priority_thread_pool'
54
+ require 'fastly_nsq/producer'
55
+ require 'fastly_nsq/tls_options'
56
+ require 'fastly_nsq/version'