eventq 2.0.0.rc1 → 2.0.0.rc2
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 +4 -4
- data/README.md +54 -24
- data/lib/eventq/aws.rb +1 -6
- data/lib/eventq/eventq_aws/aws_queue_worker.rb +17 -42
- data/lib/eventq/eventq_base/configuration.rb +2 -6
- data/lib/eventq/eventq_base/queue.rb +3 -0
- data/lib/eventq/eventq_base/serialization_providers.rb +2 -9
- data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_client.rb +1 -6
- data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_manager.rb +4 -12
- data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_worker.rb +22 -56
- data/lib/eventq/queue_worker.rb +56 -1
- data/lib/eventq/rabbitmq.rb +2 -10
- metadata +19 -35
- data/lib/eventq/eventq_aws/README.md +0 -53
- data/lib/eventq/eventq_aws/jruby/aws_queue_worker.rb +0 -370
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/array_writer.rb +0 -20
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/attribute_writer.rb +0 -24
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/class_writer.rb +0 -20
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/date_time_writer.rb +0 -33
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/date_writer.rb +0 -22
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/hash_writer.rb +0 -18
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/rational_writer.rb +0 -20
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/serializer.rb +0 -17
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/time_writer.rb +0 -18
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/value_writer.rb +0 -16
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj.rb +0 -10
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj_serialization_provider.rb +0 -25
- data/lib/eventq/eventq_base/serialization_providers/jruby.rb +0 -2
- data/lib/eventq/eventq_rabbitmq/README.md +0 -36
- 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,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,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
|
-
|