eventq 2.0.0.rc1 → 2.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +54 -24
  3. data/lib/eventq/aws.rb +1 -6
  4. data/lib/eventq/eventq_aws/aws_queue_worker.rb +17 -42
  5. data/lib/eventq/eventq_base/configuration.rb +2 -6
  6. data/lib/eventq/eventq_base/queue.rb +3 -0
  7. data/lib/eventq/eventq_base/serialization_providers.rb +2 -9
  8. data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_client.rb +1 -6
  9. data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_manager.rb +4 -12
  10. data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_worker.rb +22 -56
  11. data/lib/eventq/queue_worker.rb +56 -1
  12. data/lib/eventq/rabbitmq.rb +2 -10
  13. metadata +19 -35
  14. data/lib/eventq/eventq_aws/README.md +0 -53
  15. data/lib/eventq/eventq_aws/jruby/aws_queue_worker.rb +0 -370
  16. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/array_writer.rb +0 -20
  17. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/attribute_writer.rb +0 -24
  18. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/class_writer.rb +0 -20
  19. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/date_time_writer.rb +0 -33
  20. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/date_writer.rb +0 -22
  21. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/hash_writer.rb +0 -18
  22. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/rational_writer.rb +0 -20
  23. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/serializer.rb +0 -17
  24. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/time_writer.rb +0 -18
  25. data/lib/eventq/eventq_base/serialization_providers/jruby/oj/value_writer.rb +0 -16
  26. data/lib/eventq/eventq_base/serialization_providers/jruby/oj.rb +0 -10
  27. data/lib/eventq/eventq_base/serialization_providers/jruby/oj_serialization_provider.rb +0 -25
  28. data/lib/eventq/eventq_base/serialization_providers/jruby.rb +0 -2
  29. data/lib/eventq/eventq_rabbitmq/README.md +0 -36
  30. data/lib/eventq/eventq_rabbitmq/jruby/rabbitmq_queue_worker.rb +0 -367
@@ -1,20 +0,0 @@
1
- module EventQ
2
- module SerializationProviders
3
- module JRuby
4
- module Oj
5
- class RationalWriter < AttributeWriter
6
- def valid?(obj)
7
- obj.is_a?(Rational)
8
- end
9
- def exec(obj)
10
- {
11
- '^O': 'Rational',
12
- numerator: obj.numerator,
13
- denominator: obj.denominator
14
- }
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,17 +0,0 @@
1
- module EventQ
2
- module SerializationProviders
3
- module JRuby
4
- module Oj
5
- class Serializer
6
- def dump(obj)
7
- JSON.dump(AttributeWriter.exec(obj))
8
- end
9
-
10
- def load(json)
11
- raise NotImplementedError.new("[#{self.class}] - #load method has not yet been implemented.")
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,18 +0,0 @@
1
- module EventQ
2
- module SerializationProviders
3
- module JRuby
4
- module Oj
5
- class TimeWriter < AttributeWriter
6
- def valid?(obj)
7
- obj.is_a?(Time)
8
- end
9
- def exec(obj)
10
- {
11
- '^t': obj.to_f
12
- }
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,16 +0,0 @@
1
- module EventQ
2
- module SerializationProviders
3
- module JRuby
4
- module Oj
5
- class ValueWriter < AttributeWriter
6
- def valid?(obj)
7
- obj.is_a?(String) || obj.is_a?(Integer) || obj.is_a?(Float)
8
- end
9
- def exec(obj)
10
- obj
11
- end
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,10 +0,0 @@
1
- require_relative 'oj/attribute_writer'
2
- require_relative 'oj/class_writer'
3
- require_relative 'oj/rational_writer'
4
- require_relative 'oj/date_time_writer'
5
- require_relative 'oj/date_writer'
6
- require_relative 'oj/time_writer'
7
- require_relative 'oj/array_writer'
8
- require_relative 'oj/hash_writer'
9
- require_relative 'oj/value_writer'
10
- require_relative 'oj/serializer'
@@ -1,25 +0,0 @@
1
- module EventQ
2
- module SerializationProviders
3
- module JRuby
4
- class OjSerializationProvider
5
- def initialize
6
- @json_serializer = EventQ::SerializationProviders::JsonSerializationProvider.new
7
- @oj_serializer = Oj::Serializer.new
8
- end
9
-
10
- def serialize(object)
11
- @oj_serializer.dump(object)
12
- end
13
-
14
- def deserialize(json)
15
- begin
16
- return @oj_serializer.load(json)
17
- rescue
18
- EventQ.log(:debug, "[#{self.class}] - Failed to deserialize using Oj, falling back to JsonSerializationProvider.")
19
- return @json_serializer.deserialize(json)
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,2 +0,0 @@
1
- require_relative 'jruby/oj'
2
- require_relative 'jruby/oj_serialization_provider'
@@ -1,36 +0,0 @@
1
- # EventQ [RabbitMq]
2
-
3
- Welcome to EventQ. This gem contains the RabbitMq implementations of the EventQ framework components.
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- ```ruby
10
- gem 'eventq_rabbitmq'
11
- ```
12
-
13
- And then execute:
14
-
15
- $ bundle
16
-
17
- Or install it yourself as:
18
-
19
- $ gem install eventq_rabbitmq
20
-
21
-
22
- ## Development
23
-
24
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
25
-
26
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
27
-
28
- ## Contributing
29
-
30
- Bug reports and pull requests are welcome on GitHub at https://github.com/sage/eventq. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
31
-
32
-
33
- ## License
34
-
35
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
36
-
@@ -1,367 +0,0 @@
1
- require 'java'
2
- java_import java.util.concurrent.Executors
3
- module EventQ
4
- module RabbitMq
5
- class QueueWorker
6
- include EventQ::WorkerId
7
-
8
- attr_accessor :is_running
9
-
10
- def initialize
11
- @is_running = false
12
-
13
- @retry_exceeded_block = nil
14
- @on_retry_block = nil
15
- @on_error_block = nil
16
- @hash_helper = HashKit::Helper.new
17
- @serialization_provider_manager = EventQ::SerializationProviders::Manager.new
18
- @signature_provider_manager = EventQ::SignatureProviders::Manager.new
19
- @last_gc_flush = Time.now
20
- @gc_flush_interval = 10
21
- end
22
-
23
- def start(queue, options = {}, &block)
24
-
25
- EventQ.logger.info("[#{self.class}] - Preparing to start listening for messages.")
26
-
27
- configure(queue, options)
28
-
29
- raise "[#{self.class}] - Worker is already running." if running?
30
-
31
- if options[:client] == nil
32
- raise "[#{self.class}] - :client (QueueClient) must be specified."
33
- end
34
-
35
- EventQ.logger.info("[#{self.class}] - Listening for messages.")
36
- EventQ.logger.debug do
37
- "[#{self.class} #start] - Listening for messages on queue: #{EventQ.create_queue_name(queue.name)}"
38
- end
39
-
40
- start_process(options, queue, block)
41
-
42
- return true
43
- end
44
-
45
- def start_process(options, queue, block)
46
-
47
- @is_running = true
48
-
49
- %w'INT TERM'.each do |sig|
50
- Signal.trap(sig) {
51
- stop
52
- exit
53
- }
54
- end
55
-
56
- if !options.key?(:durable)
57
- options[:durable] = true
58
- end
59
-
60
- client = options[:client]
61
- manager = EventQ::RabbitMq::QueueManager.new
62
- manager.durable = options[:durable]
63
- @connection = client.get_connection
64
-
65
- @executor = java.util.concurrent.Executors::newFixedThreadPool @thread_count
66
-
67
- #loop through each thread count
68
- @thread_count.times do
69
-
70
- @executor.execute do
71
-
72
- #begin the queue loop for this thread
73
- while true do
74
-
75
- #check if the worker is still allowed to run and break out of thread loop if not
76
- unless running?
77
- break
78
- end
79
-
80
- if @executor.is_shutdown
81
- break
82
- end
83
-
84
- has_received_message = false
85
-
86
- begin
87
-
88
- channel = @connection.create_channel
89
-
90
- has_received_message = thread_process_iteration(channel, manager, queue, block)
91
-
92
- rescue => e
93
- EventQ.logger.error("An unhandled error occurred. Error: #{e} | Backtrace: #{e.backtrace}")
94
- call_on_error_block(error: e)
95
- end
96
-
97
- if channel != nil && channel.open?
98
- channel.close
99
- end
100
-
101
- gc_flush
102
-
103
- if !has_received_message
104
- EventQ.logger.debug { "[#{self.class}] - No message received." }
105
- if @sleep > 0
106
- EventQ.logger.debug { "[#{self.class}] - Sleeping for #{@sleep} seconds" }
107
- sleep(@sleep)
108
- end
109
- end
110
-
111
- end
112
-
113
- end
114
-
115
- end
116
-
117
- if options.key?(:wait) && options[:wait] == true
118
- while running? do end
119
- @connection.close if @connection.open?
120
- end
121
-
122
- return true
123
-
124
- end
125
-
126
- def call_on_error_block(error:, message: nil)
127
- if @on_error_block
128
- EventQ.logger.debug { "[#{self.class}] - Executing on_error block." }
129
- begin
130
- @on_error_block.call(error, message)
131
- rescue => e
132
- EventQ.logger.error("[#{self.class}] - An error occurred executing the on_error block. Error: #{e}")
133
- end
134
- else
135
- EventQ.logger.debug { "[#{self.class}] - No on_error block specified to execute." }
136
- end
137
- end
138
-
139
- def gc_flush
140
- if Time.now - last_gc_flush > @gc_flush_interval
141
- GC.start
142
- @last_gc_flush = Time.now
143
- end
144
- end
145
-
146
- def last_gc_flush
147
- @last_gc_flush
148
- end
149
-
150
- def thread_process_iteration(channel, manager, queue, block)
151
-
152
- #get the queue
153
- q = manager.get_queue(channel, queue)
154
- retry_exchange = manager.get_retry_exchange(channel, queue)
155
-
156
- received = false
157
-
158
- begin
159
- delivery_info, payload = manager.pop_message(queue: q)
160
-
161
- #check that message was received
162
- if payload != nil
163
- received = true
164
- begin
165
- tag_processing_thread
166
- process_message(payload, queue, channel, retry_exchange, delivery_info, block)
167
- ensure
168
- untag_processing_thread
169
- end
170
-
171
- end
172
-
173
- rescue => e
174
- EventQ.logger.error("[#{self.class}] - An error occurred attempting to process a message. Error: #{e} | Backtrace: #{e.backtrace}")
175
- call_on_error_block(error: e)
176
- end
177
-
178
- return received
179
- end
180
-
181
- def stop
182
- EventQ.logger.info { "[#{self.class}] - Stopping..." }
183
- @is_running = false
184
- @executor.shutdown
185
- if @connection != nil
186
- @connection.close if @connection.open?
187
- end
188
- return true
189
- end
190
-
191
- def on_retry_exceeded(&block)
192
- @retry_exceeded_block = block
193
- return nil
194
- end
195
-
196
- def on_retry(&block)
197
- @on_retry_block = block
198
- return nil
199
- end
200
-
201
- def on_error(&block)
202
- @on_error_block = block
203
- return nil
204
- end
205
-
206
- def running?
207
- return @is_running
208
- end
209
-
210
- def deserialize_message(payload)
211
- provider = @serialization_provider_manager.get_provider(EventQ::Configuration.serialization_provider)
212
- return provider.deserialize(payload)
213
- end
214
-
215
- def serialize_message(msg)
216
- provider = @serialization_provider_manager.get_provider(EventQ::Configuration.serialization_provider)
217
- return provider.serialize(msg)
218
- end
219
-
220
- def call_on_retry_exceeded_block(message)
221
- if @retry_exceeded_block != nil
222
- EventQ.logger.debug { "[#{self.class}] - Executing on_retry_exceeded block." }
223
- begin
224
- @retry_exceeded_block.call(message)
225
- rescue => e
226
- EventQ.logger.error("[#{self.class}] - An error occurred executing the on_retry_exceeded block. Error: #{e}")
227
- end
228
- else
229
- EventQ.logger.debug { "[#{self.class}] - No on_retry_exceeded block specified." }
230
- end
231
- end
232
-
233
- def call_on_retry_block(message)
234
- if @on_retry_block
235
- EventQ.logger.debug { "[#{self.class}] - Executing on_retry block." }
236
- begin
237
- @on_retry_block.call(message, abort)
238
- rescue => e
239
- EventQ.logger.error("[#{self.class}] - An error occurred executing the on_retry block. Error: #{e}")
240
- end
241
- else
242
- EventQ.logger.debug { "[#{self.class}] - No on_retry block specified." }
243
- end
244
- end
245
-
246
- def reject_message(channel, message, delivery_tag, retry_exchange, queue, abort)
247
-
248
- EventQ.logger.info("[#{self.class}] - Message rejected removing from queue.")
249
- #reject the message to remove from queue
250
- channel.reject(delivery_tag, false)
251
-
252
- #check if the message retry limit has been exceeded
253
- if message.retry_attempts >= queue.max_retry_attempts
254
-
255
- EventQ.logger.info("[#{self.class}] - Message retry attempt limit exceeded. Msg: #{serialize_message(message)}")
256
-
257
- call_on_retry_exceeded_block(message)
258
-
259
- #check if the message is allowed to be retried
260
- elsif queue.allow_retry
261
-
262
- EventQ.logger.debug { "[#{self.class}] - Incrementing retry attempts count." }
263
- message.retry_attempts += 1
264
-
265
- if queue.allow_retry_back_off == true
266
- EventQ.logger.debug { "[#{self.class}] - Calculating message back off retry delay. Attempts: #{message.retry_attempts} * Retry Delay: #{queue.retry_delay}" }
267
- message_ttl = message.retry_attempts * queue.retry_delay
268
- if (message.retry_attempts * queue.retry_delay) > queue.max_retry_delay
269
- EventQ.logger.debug { "[#{self.class}] - Max message back off retry delay reached." }
270
- message_ttl = queue.max_retry_delay
271
- end
272
- else
273
- EventQ.logger.debug { "[#{self.class}] - Setting fixed retry delay for message." }
274
- message_ttl = queue.retry_delay
275
- end
276
-
277
- EventQ.logger.debug { "[#{self.class}] - Sending message for retry. Message TTL: #{message_ttl}" }
278
- retry_exchange.publish(serialize_message(message), :expiration => message_ttl)
279
- EventQ.logger.debug { "[#{self.class}] - Published message to retry exchange." }
280
-
281
- call_on_retry_block(message)
282
-
283
- end
284
-
285
- return true
286
-
287
- end
288
-
289
- def configure(queue, options = {})
290
-
291
- @queue = queue
292
-
293
- #default thread count
294
- @thread_count = 4
295
- if options.key?(:thread_count)
296
- @thread_count = options[:thread_count]
297
- end
298
-
299
- #default sleep time in seconds
300
- @sleep = 15
301
- if options.key?(:sleep)
302
- @sleep = options[:sleep]
303
- end
304
-
305
- @gc_flush_interval = 10
306
- if options.key?(:gc_flush_interval)
307
- @gc_flush_interval = options[:gc_flush_interval]
308
- end
309
-
310
- EventQ.logger.info("[#{self.class}] - Configuring. Thread Count: #{@thread_count} | Interval Sleep: #{@sleep}.")
311
-
312
- return true
313
-
314
- end
315
-
316
- private
317
-
318
- def process_message(payload, queue, channel, retry_exchange, delivery_tag, block)
319
- abort = false
320
- error = false
321
- message = deserialize_message(payload)
322
-
323
- EventQ.logger.info("[#{self.class}] - Message received. Retry Attempts: #{message.retry_attempts}")
324
-
325
- @signature_provider_manager.validate_signature(message: message, queue: queue)
326
-
327
- message_args = EventQ::MessageArgs.new(type: message.type,
328
- retry_attempts: message.retry_attempts,
329
- context: message.context,
330
- content_type: message.content_type)
331
-
332
- if(!EventQ::NonceManager.is_allowed?(message.id))
333
- EventQ.logger.info("[#{self.class}] - Duplicate Message received. Dropping message.")
334
- channel.acknowledge(delivery_tag, false)
335
- return false
336
- end
337
-
338
- #begin worker block for queue message
339
- begin
340
- block.call(message.content, message_args)
341
-
342
- if message_args.abort == true
343
- abort = true
344
- EventQ.logger.info("[#{self.class}] - Message aborted.")
345
- else
346
- #accept the message as processed
347
- channel.acknowledge(delivery_tag, false)
348
- EventQ.logger.info("[#{self.class}] - Message acknowledged.")
349
- end
350
-
351
- rescue => e
352
- EventQ.logger.error("[#{self.class}] - An unhandled error happened attempting to process a queue message. Error: #{e} | Backtrace: #{e.backtrace}")
353
- error = true
354
- call_on_error_block(error: e, message: message)
355
- end
356
-
357
- if error || abort
358
- EventQ::NonceManager.failed(message.id)
359
- reject_message(channel, message, delivery_tag, retry_exchange, queue, abort)
360
- else
361
- EventQ::NonceManager.complete(message.id)
362
- end
363
- end
364
- end
365
- end
366
- end
367
-