emque-consuming 1.1.3 → 1.2.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.
- data/CHANGELOG.md +2 -1
- data/README.md +16 -0
- data/lib/emque/consuming/adapters/rabbit_mq/delayed_message_worker.rb +87 -0
- data/lib/emque/consuming/adapters/rabbit_mq/{retry_worker.rb → error_worker.rb} +2 -2
- data/lib/emque/consuming/adapters/rabbit_mq/manager.rb +31 -3
- data/lib/emque/consuming/adapters/rabbit_mq/worker.rb +44 -2
- data/lib/emque/consuming/adapters/rabbit_mq.rb +2 -1
- data/lib/emque/consuming/cli.rb +8 -0
- data/lib/emque/consuming/configuration.rb +24 -14
- data/lib/emque/consuming/consumer.rb +1 -0
- data/lib/emque/consuming/retryable_errors.rb +37 -0
- data/lib/emque/consuming/version.rb +1 -1
- data/spec/configuration_spec.rb +44 -3
- data/spec/retryable_errors_spec.rb +18 -0
- metadata +65 -33
- checksums.yaml +0 -7
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Emque Consuming CHANGELOG
|
2
2
|
|
3
|
+
- [Add in the ability to retry errors and back off with an exponential delay](https://github.com/emque/emque-consuming/pull/55) 1.2.0
|
3
4
|
- [Add in a configuration option to disable auto shutdown on reaching the error limit](https://github.com/emque/emque-consuming/pull/58) 1.1.3
|
4
5
|
|
5
6
|
## 1.0.0.beta4
|
@@ -10,6 +11,6 @@ After starting up, messages will need to be manually moved
|
|
10
11
|
from the old queue to the new one.
|
11
12
|
|
12
13
|
### Failed Message Routing
|
13
|
-
Messages that are not
|
14
|
+
Messages that are not acknowledged due to a consumer error will now be routed
|
14
15
|
into a `service_name.error` queue. These can then be inspected and be discarded,
|
15
16
|
purged, or manually moved back to the primary queue for re-processing.
|
data/README.md
CHANGED
@@ -59,6 +59,22 @@ emque <options> (start|stop|new|console|help) <name (new only)>
|
|
59
59
|
# ...
|
60
60
|
```
|
61
61
|
|
62
|
+
### Automatic Error Retries
|
63
|
+
|
64
|
+
In 1.2.0 the ability to automatically retry specific types of errors was introduced.
|
65
|
+
This depends on the [Delayed Message Exchange](https://github.com/rabbitmq/rabbitmq-delayed-message-exchange) plugin. After
|
66
|
+
[installing the plugin](https://github.com/rabbitmq/rabbitmq-delayed-message-exchange#installing),
|
67
|
+
you'll need to configure emque consuming to utilize the plugin:
|
68
|
+
|
69
|
+
```
|
70
|
+
config.enable_delayed_message = true # turn on retryable errors, defaults to false
|
71
|
+
config.retryable_errors = ["ExampleError"] # a comma delimited array of strings matching the error, defaults to any empty array ([])
|
72
|
+
config.retryable_error_limit = 4 # the number of retries to use before dead lettering the message, defaults to 3
|
73
|
+
config.delayed_message_workers = 3 # the number of workers processing delayed messages, defaults to 1
|
74
|
+
```
|
75
|
+
|
76
|
+
This will now allow you to retry known errors with an exponential backoff, which should help with transient errors!
|
77
|
+
|
62
78
|
### Custom
|
63
79
|
|
64
80
|
Configure Emque::Consuming in your config/application.rb file. Here is an example:
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "bunny"
|
2
|
+
|
3
|
+
module Emque
|
4
|
+
module Consuming
|
5
|
+
module Adapters
|
6
|
+
module RabbitMq
|
7
|
+
class DelayedMessageWorker
|
8
|
+
include Emque::Consuming::Actor
|
9
|
+
include Emque::Consuming::RetryableErrors
|
10
|
+
trap_exit :actor_died
|
11
|
+
|
12
|
+
def actor_died(actor, reason)
|
13
|
+
unless shutdown
|
14
|
+
logger.error "#{log_prefix} actor_died - died: #{reason}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(connection)
|
19
|
+
self.channel = connection.create_channel
|
20
|
+
|
21
|
+
self.delayed_message_exchange = channel.exchange(
|
22
|
+
"emque.#{config.app_name}.delayed_message",
|
23
|
+
{
|
24
|
+
:type => "x-delayed-message",
|
25
|
+
:durable => true,
|
26
|
+
:auto_delete => false,
|
27
|
+
:arguments => {
|
28
|
+
"x-delayed-type" => "direct",
|
29
|
+
}
|
30
|
+
}
|
31
|
+
)
|
32
|
+
|
33
|
+
self.queue = channel.queue(
|
34
|
+
"emque.#{config.app_name}.delayed_message",
|
35
|
+
:durable => config.adapter.options[:durable],
|
36
|
+
:auto_delete => config.adapter.options[:auto_delete],
|
37
|
+
:arguments => {
|
38
|
+
"x-dead-letter-exchange" => "#{config.app_name}.error"
|
39
|
+
}
|
40
|
+
).bind(delayed_message_exchange)
|
41
|
+
end
|
42
|
+
|
43
|
+
def start
|
44
|
+
logger.info "#{log_prefix} starting..."
|
45
|
+
queue.subscribe(:manual_ack => true, &method(:process_message))
|
46
|
+
logger.debug "#{log_prefix} started"
|
47
|
+
end
|
48
|
+
|
49
|
+
def stop
|
50
|
+
logger.debug "#{log_prefix} stopping..."
|
51
|
+
super do
|
52
|
+
logger.debug "#{log_prefix} closing channel"
|
53
|
+
channel.close
|
54
|
+
end
|
55
|
+
logger.debug "#{log_prefix} stopped"
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
attr_accessor :channel, :delayed_message_exchange, :queue
|
61
|
+
|
62
|
+
def process_message(delivery_info, metadata, payload)
|
63
|
+
begin
|
64
|
+
logger.info "#{log_prefix} processing message #{metadata}"
|
65
|
+
logger.debug "#{log_prefix} payload #{payload}"
|
66
|
+
message = Emque::Consuming::Message.new(
|
67
|
+
:original => payload
|
68
|
+
)
|
69
|
+
::Emque::Consuming::Consumer.new.consume(:process, message)
|
70
|
+
channel.ack(delivery_info.delivery_tag)
|
71
|
+
rescue StandardError => ex
|
72
|
+
if retryable_errors.any? { |error| ex.class.to_s =~ /#{error}/ }
|
73
|
+
retry_error(delivery_info, metadata, payload, ex)
|
74
|
+
else
|
75
|
+
channel.nack(delivery_info.delivery_tag)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def log_prefix
|
81
|
+
"RabbitMQ DelayedMessageWorker:"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -4,7 +4,7 @@ module Emque
|
|
4
4
|
module Consuming
|
5
5
|
module Adapters
|
6
6
|
module RabbitMq
|
7
|
-
class
|
7
|
+
class ErrorWorker
|
8
8
|
include Emque::Consuming::Helpers
|
9
9
|
|
10
10
|
def initialize(connection)
|
@@ -43,7 +43,7 @@ module Emque
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def log_prefix
|
46
|
-
"RabbitMQ
|
46
|
+
"RabbitMQ ErrorWorker:"
|
47
47
|
end
|
48
48
|
|
49
49
|
def retry_message(delivery_info, metadata, payload)
|
@@ -10,7 +10,7 @@ module Emque
|
|
10
10
|
|
11
11
|
def actor_died(actor, reason)
|
12
12
|
unless shutdown
|
13
|
-
logger.error "RabbitMQ Manager: actor_died - #{actor.inspect} "+
|
13
|
+
logger.error "RabbitMQ Manager: actor_died - #{actor.inspect} " +
|
14
14
|
"died: #{reason}"
|
15
15
|
end
|
16
16
|
end
|
@@ -19,10 +19,16 @@ module Emque
|
|
19
19
|
setup_connection
|
20
20
|
initialize_error_queue
|
21
21
|
initialize_workers
|
22
|
+
initialize_delayed_message_workers if enable_delayed_message
|
22
23
|
logger.info "RabbitMQ Manager: starting #{worker_count} workers..."
|
23
24
|
workers(:flatten => true).each do |worker|
|
24
25
|
worker.async.start
|
25
26
|
end
|
27
|
+
if enable_delayed_message
|
28
|
+
delayed_message_workers.each do |worker|
|
29
|
+
worker.async.start
|
30
|
+
end
|
31
|
+
end
|
26
32
|
end
|
27
33
|
|
28
34
|
def stop
|
@@ -33,6 +39,12 @@ module Emque
|
|
33
39
|
logger.info "RabbitMQ Manager: stopping #{worker.topic} worker..."
|
34
40
|
worker.stop
|
35
41
|
end
|
42
|
+
if enable_delayed_message
|
43
|
+
delayed_message_workers.each_with_index do |worker, i|
|
44
|
+
logger.info "RabbitMQ Manager: stopping #{worker.class} #{i + 1} worker..."
|
45
|
+
worker.stop
|
46
|
+
end
|
47
|
+
end
|
36
48
|
end
|
37
49
|
|
38
50
|
@connection.stop
|
@@ -55,13 +67,17 @@ module Emque
|
|
55
67
|
flatten ? @workers.values.flatten : @workers
|
56
68
|
end
|
57
69
|
|
70
|
+
def delayed_message_workers
|
71
|
+
@delayed_message_workers
|
72
|
+
end
|
73
|
+
|
58
74
|
def retry_errors
|
59
|
-
|
75
|
+
ErrorWorker.new(@connection).retry_errors
|
60
76
|
end
|
61
77
|
|
62
78
|
private
|
63
79
|
|
64
|
-
attr_writer :workers
|
80
|
+
attr_writer :workers, :delayed_message_workers
|
65
81
|
|
66
82
|
def initialize_workers
|
67
83
|
self.workers = {}.tap { |workers|
|
@@ -74,6 +90,18 @@ module Emque
|
|
74
90
|
}
|
75
91
|
end
|
76
92
|
|
93
|
+
def initialize_delayed_message_workers
|
94
|
+
self.delayed_message_workers = [].tap { |workers|
|
95
|
+
config.delayed_message_workers.times do
|
96
|
+
workers << DelayedMessageWorker.new_link(@connection)
|
97
|
+
end
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
def enable_delayed_message
|
102
|
+
config.enable_delayed_message
|
103
|
+
end
|
104
|
+
|
77
105
|
def initialize_error_queue
|
78
106
|
channel = @connection.create_channel
|
79
107
|
error_exchange = channel.fanout(
|
@@ -6,6 +6,7 @@ module Emque
|
|
6
6
|
module RabbitMq
|
7
7
|
class Worker
|
8
8
|
include Emque::Consuming::Actor
|
9
|
+
include Emque::Consuming::RetryableErrors
|
9
10
|
trap_exit :actor_died
|
10
11
|
|
11
12
|
attr_accessor :topic
|
@@ -64,6 +65,10 @@ module Emque
|
|
64
65
|
|
65
66
|
attr_accessor :name, :channel, :queue
|
66
67
|
|
68
|
+
def enable_delayed_message
|
69
|
+
config.enable_delayed_message
|
70
|
+
end
|
71
|
+
|
67
72
|
def process_message(delivery_info, metadata, payload)
|
68
73
|
begin
|
69
74
|
logger.info "#{log_prefix} processing message #{metadata}"
|
@@ -73,11 +78,48 @@ module Emque
|
|
73
78
|
)
|
74
79
|
::Emque::Consuming::Consumer.new.consume(:process, message)
|
75
80
|
channel.ack(delivery_info.delivery_tag)
|
76
|
-
rescue StandardError
|
77
|
-
|
81
|
+
rescue StandardError => ex
|
82
|
+
if enable_delayed_message
|
83
|
+
publish_to_delayed_message(delivery_info, metadata, payload)
|
84
|
+
else
|
85
|
+
channel.nack(delivery_info.delivery_tag)
|
86
|
+
end
|
87
|
+
ensure
|
88
|
+
channel.ack(delivery_info.delivery_tag)
|
78
89
|
end
|
79
90
|
end
|
80
91
|
|
92
|
+
def publish_to_delayed_message(delivery_info, metadata, payload)
|
93
|
+
headers = metadata[:headers] || {}
|
94
|
+
headers["x-delay"] = 1000
|
95
|
+
delayed_message_exchange.publish(payload, { :headers => headers })
|
96
|
+
channel.ack(delivery_info.delivery_tag)
|
97
|
+
end
|
98
|
+
|
99
|
+
def delayed_message_exchange
|
100
|
+
delayed_message_exchange = channel.exchange(
|
101
|
+
"emque.#{config.app_name}.delayed_message",
|
102
|
+
{
|
103
|
+
:type => "x-delayed-message",
|
104
|
+
:durable => true,
|
105
|
+
:auto_delete => false,
|
106
|
+
:arguments => {
|
107
|
+
"x-delayed-type" => "direct",
|
108
|
+
}
|
109
|
+
}
|
110
|
+
)
|
111
|
+
channel.queue(
|
112
|
+
"emque.#{config.app_name}.delayed_message",
|
113
|
+
:durable => config.adapter.options[:durable],
|
114
|
+
:auto_delete => config.adapter.options[:auto_delete],
|
115
|
+
:arguments => {
|
116
|
+
"x-dead-letter-exchange" => "#{config.app_name}.error"
|
117
|
+
}
|
118
|
+
).bind(delayed_message_exchange)
|
119
|
+
|
120
|
+
delayed_message_exchange
|
121
|
+
end
|
122
|
+
|
81
123
|
def log_prefix
|
82
124
|
"RabbitMQ Worker: #{object_id} #{name}"
|
83
125
|
end
|
@@ -14,7 +14,8 @@ module Emque
|
|
14
14
|
def self.load
|
15
15
|
require_relative "rabbit_mq/manager"
|
16
16
|
require_relative "rabbit_mq/worker"
|
17
|
-
require_relative "rabbit_mq/
|
17
|
+
require_relative "rabbit_mq/error_worker"
|
18
|
+
require_relative "rabbit_mq/delayed_message_worker"
|
18
19
|
end
|
19
20
|
|
20
21
|
def self.manager
|
data/lib/emque/consuming/cli.rb
CHANGED
@@ -144,6 +144,14 @@ module Emque
|
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
147
|
+
o.on(
|
148
|
+
"--retry-error-limit N",
|
149
|
+
"Max number of times to retry a retryable error"
|
150
|
+
) do |arg|
|
151
|
+
retry_limit = arg.to_i
|
152
|
+
options[:retryable_error_limit] = retry_limit if retry_limit > 0
|
153
|
+
end
|
154
|
+
|
147
155
|
o.banner = "emque <options> (start|stop|new|console|help) <name (new only)>"
|
148
156
|
}
|
149
157
|
end
|
@@ -3,23 +3,29 @@ require "logger"
|
|
3
3
|
module Emque
|
4
4
|
module Consuming
|
5
5
|
class Configuration
|
6
|
-
attr_accessor :app_name, :
|
7
|
-
:
|
6
|
+
attr_accessor :app_name, :adapter, :auto_shutdown,
|
7
|
+
:delayed_message_workers, :enable_delayed_message, :error_handlers,
|
8
|
+
:error_limit, :error_expiration, :retryable_errors,
|
9
|
+
:retryable_error_limit, :status, :status_port, :status_host,
|
8
10
|
:socket_path, :shutdown_handlers
|
9
11
|
attr_writer :env, :log_level
|
10
12
|
|
11
13
|
def initialize
|
12
|
-
@app_name
|
13
|
-
@auto_shutdown
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
14
|
+
@app_name = ""
|
15
|
+
@auto_shutdown = false
|
16
|
+
@delayed_message_workers = 1
|
17
|
+
@enable_delayed_message = false
|
18
|
+
@error_handlers = []
|
19
|
+
@error_limit = 5
|
20
|
+
@error_expiration = 3600 # 60 minutes
|
21
|
+
@log_level = nil
|
22
|
+
@retryable_errors = []
|
23
|
+
@retryable_error_limit = 3
|
24
|
+
@status_port = 10000
|
25
|
+
@status_host = "0.0.0.0"
|
26
|
+
@status = :off # :on
|
27
|
+
@socket_path = "tmp/emque.sock"
|
28
|
+
@shutdown_handlers = []
|
23
29
|
end
|
24
30
|
|
25
31
|
def env
|
@@ -42,13 +48,17 @@ module Emque
|
|
42
48
|
{}.tap { |config|
|
43
49
|
[
|
44
50
|
:app_name,
|
45
|
-
:auto_shutdown,
|
46
51
|
:adapter,
|
52
|
+
:auto_shutdown,
|
53
|
+
:delayed_message_workers,
|
47
54
|
:env,
|
55
|
+
:enable_delayed_message,
|
48
56
|
:error_handlers,
|
49
57
|
:error_limit,
|
50
58
|
:error_expiration,
|
51
59
|
:log_level,
|
60
|
+
:retryable_errors,
|
61
|
+
:retryable_error_limit,
|
52
62
|
:status_port,
|
53
63
|
:status_host,
|
54
64
|
:status,
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Emque
|
2
|
+
module Consuming
|
3
|
+
module RetryableErrors
|
4
|
+
include Emque::Consuming::Helpers
|
5
|
+
|
6
|
+
def retryable_errors
|
7
|
+
config.retryable_errors
|
8
|
+
end
|
9
|
+
|
10
|
+
def retryable_error_limit
|
11
|
+
config.retryable_error_limit
|
12
|
+
end
|
13
|
+
|
14
|
+
def delay_ms_time(retry_count)
|
15
|
+
retry_count * 500 * ( 2 ** retry_count)
|
16
|
+
end
|
17
|
+
|
18
|
+
def retry_error(delivery_info, metadata, payload, ex)
|
19
|
+
headers = metadata[:headers] || {}
|
20
|
+
retry_count = headers.fetch("x-retry-count", 0)
|
21
|
+
|
22
|
+
if retry_count <= retryable_error_limit
|
23
|
+
logger.info("Retrying Retryable Error #{ex.class}, with count " +
|
24
|
+
"#{retry_count}")
|
25
|
+
headers["x-retry-count"] = retry_count + 1
|
26
|
+
headers["x-delay"] = delay_ms_time(retry_count)
|
27
|
+
channel.ack(delivery_info.delivery_tag)
|
28
|
+
delayed_message_exchange.publish(payload, { :headers => headers })
|
29
|
+
else
|
30
|
+
logger.info("Retryable Error: #{ex.class} ran out of retries at " +
|
31
|
+
"#{retry_count}")
|
32
|
+
channel.nack(delivery_info.delivery_tag)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -14,6 +14,45 @@ describe Emque::Consuming::Configuration do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
describe "delayed_message_workers" do
|
18
|
+
it "has a default" do
|
19
|
+
config = Emque::Consuming::Configuration.new
|
20
|
+
expect(config.delayed_message_workers).to eq(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "prefers the assigned value" do
|
24
|
+
config = Emque::Consuming::Configuration.new
|
25
|
+
config.delayed_message_workers = 2
|
26
|
+
expect(config.delayed_message_workers).to eq(2)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "retryable_errors" do
|
31
|
+
it "has a default" do
|
32
|
+
config = Emque::Consuming::Configuration.new
|
33
|
+
expect(config.retryable_errors).to eq([])
|
34
|
+
end
|
35
|
+
|
36
|
+
it "prefers the assigned value" do
|
37
|
+
config = Emque::Consuming::Configuration.new
|
38
|
+
config.retryable_errors = ["TestError"]
|
39
|
+
expect(config.retryable_errors).to eq(["TestError"])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "retryable_error_limit" do
|
44
|
+
it "has a default" do
|
45
|
+
config = Emque::Consuming::Configuration.new
|
46
|
+
expect(config.retryable_error_limit).to eq(3)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "prefers the assigned value" do
|
50
|
+
config = Emque::Consuming::Configuration.new
|
51
|
+
config.retryable_error_limit = 4
|
52
|
+
expect(config.retryable_error_limit).to eq(4)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
17
56
|
describe "#to_hsh" do
|
18
57
|
it "returns a hash" do
|
19
58
|
config = Emque::Consuming::Configuration.new
|
@@ -22,9 +61,11 @@ describe Emque::Consuming::Configuration do
|
|
22
61
|
|
23
62
|
it "returns the value of all the accessors" do
|
24
63
|
accessors = [
|
25
|
-
:app_name, :
|
26
|
-
:
|
27
|
-
:
|
64
|
+
:app_name, :adapter, :auto_shutdown, :delayed_message_workers,
|
65
|
+
:env, :enable_delayed_message, :error_handlers, :error_limit,
|
66
|
+
:error_expiration, :log_level, :retryable_errors,
|
67
|
+
:retryable_error_limit, :status_port, :status_host, :status,
|
68
|
+
:socket_path, :shutdown_handlers
|
28
69
|
]
|
29
70
|
config = Emque::Consuming::Configuration.new
|
30
71
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "emque/consuming/retryable_errors"
|
3
|
+
|
4
|
+
describe Emque::Consuming::RetryableErrors do
|
5
|
+
describe "retryable errors" do
|
6
|
+
it "exponentially backs off the delay time" do
|
7
|
+
test_class = Class.new { include Emque::Consuming::RetryableErrors }
|
8
|
+
test = test_class.new
|
9
|
+
retry1 = test.delay_ms_time(1)
|
10
|
+
retry2 = test.delay_ms_time(2)
|
11
|
+
retry3 = test.delay_ms_time(3)
|
12
|
+
|
13
|
+
expect(retry1).to eq(1000)
|
14
|
+
expect(retry2).to eq(4000)
|
15
|
+
expect(retry3).to eq(12000)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emque-consuming
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Ryan Williams
|
@@ -14,6 +15,7 @@ dependencies:
|
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: celluloid
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
17
19
|
requirements:
|
18
20
|
- - '='
|
19
21
|
- !ruby/object:Gem::Version
|
@@ -21,6 +23,7 @@ dependencies:
|
|
21
23
|
type: :runtime
|
22
24
|
prerelease: false
|
23
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
24
27
|
requirements:
|
25
28
|
- - '='
|
26
29
|
- !ruby/object:Gem::Version
|
@@ -28,169 +31,193 @@ dependencies:
|
|
28
31
|
- !ruby/object:Gem::Dependency
|
29
32
|
name: dante
|
30
33
|
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
31
35
|
requirements:
|
32
|
-
- -
|
36
|
+
- - ~>
|
33
37
|
- !ruby/object:Gem::Version
|
34
38
|
version: 0.2.0
|
35
39
|
type: :runtime
|
36
40
|
prerelease: false
|
37
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
38
43
|
requirements:
|
39
|
-
- -
|
44
|
+
- - ~>
|
40
45
|
- !ruby/object:Gem::Version
|
41
46
|
version: 0.2.0
|
42
47
|
- !ruby/object:Gem::Dependency
|
43
48
|
name: oj
|
44
49
|
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
45
51
|
requirements:
|
46
|
-
- -
|
52
|
+
- - ~>
|
47
53
|
- !ruby/object:Gem::Version
|
48
54
|
version: 2.11.4
|
49
55
|
type: :runtime
|
50
56
|
prerelease: false
|
51
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
52
59
|
requirements:
|
53
|
-
- -
|
60
|
+
- - ~>
|
54
61
|
- !ruby/object:Gem::Version
|
55
62
|
version: 2.11.4
|
56
63
|
- !ruby/object:Gem::Dependency
|
57
64
|
name: virtus
|
58
65
|
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
59
67
|
requirements:
|
60
|
-
- -
|
68
|
+
- - ~>
|
61
69
|
- !ruby/object:Gem::Version
|
62
70
|
version: '1.0'
|
63
71
|
type: :runtime
|
64
72
|
prerelease: false
|
65
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
66
75
|
requirements:
|
67
|
-
- -
|
76
|
+
- - ~>
|
68
77
|
- !ruby/object:Gem::Version
|
69
78
|
version: '1.0'
|
70
79
|
- !ruby/object:Gem::Dependency
|
71
80
|
name: puma
|
72
81
|
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
73
83
|
requirements:
|
74
|
-
- -
|
84
|
+
- - ~>
|
75
85
|
- !ruby/object:Gem::Version
|
76
86
|
version: 2.11.1
|
77
87
|
type: :runtime
|
78
88
|
prerelease: false
|
79
89
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
80
91
|
requirements:
|
81
|
-
- -
|
92
|
+
- - ~>
|
82
93
|
- !ruby/object:Gem::Version
|
83
94
|
version: 2.11.1
|
84
95
|
- !ruby/object:Gem::Dependency
|
85
96
|
name: pipe-ruby
|
86
97
|
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
87
99
|
requirements:
|
88
|
-
- -
|
100
|
+
- - ~>
|
89
101
|
- !ruby/object:Gem::Version
|
90
102
|
version: 0.2.0
|
91
103
|
type: :runtime
|
92
104
|
prerelease: false
|
93
105
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
94
107
|
requirements:
|
95
|
-
- -
|
108
|
+
- - ~>
|
96
109
|
- !ruby/object:Gem::Version
|
97
110
|
version: 0.2.0
|
98
111
|
- !ruby/object:Gem::Dependency
|
99
112
|
name: inflecto
|
100
113
|
requirement: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
101
115
|
requirements:
|
102
|
-
- -
|
116
|
+
- - ~>
|
103
117
|
- !ruby/object:Gem::Version
|
104
118
|
version: 0.0.2
|
105
119
|
type: :runtime
|
106
120
|
prerelease: false
|
107
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
108
123
|
requirements:
|
109
|
-
- -
|
124
|
+
- - ~>
|
110
125
|
- !ruby/object:Gem::Version
|
111
126
|
version: 0.0.2
|
112
127
|
- !ruby/object:Gem::Dependency
|
113
128
|
name: bundler
|
114
129
|
requirement: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
115
131
|
requirements:
|
116
|
-
- -
|
132
|
+
- - ~>
|
117
133
|
- !ruby/object:Gem::Version
|
118
134
|
version: '1.7'
|
119
135
|
type: :development
|
120
136
|
prerelease: false
|
121
137
|
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
122
139
|
requirements:
|
123
|
-
- -
|
140
|
+
- - ~>
|
124
141
|
- !ruby/object:Gem::Version
|
125
142
|
version: '1.7'
|
126
143
|
- !ruby/object:Gem::Dependency
|
127
144
|
name: rake
|
128
145
|
requirement: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
129
147
|
requirements:
|
130
|
-
- -
|
148
|
+
- - ~>
|
131
149
|
- !ruby/object:Gem::Version
|
132
150
|
version: 10.4.2
|
133
151
|
type: :development
|
134
152
|
prerelease: false
|
135
153
|
version_requirements: !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
136
155
|
requirements:
|
137
|
-
- -
|
156
|
+
- - ~>
|
138
157
|
- !ruby/object:Gem::Version
|
139
158
|
version: 10.4.2
|
140
159
|
- !ruby/object:Gem::Dependency
|
141
160
|
name: rspec
|
142
161
|
requirement: !ruby/object:Gem::Requirement
|
162
|
+
none: false
|
143
163
|
requirements:
|
144
|
-
- -
|
164
|
+
- - ~>
|
145
165
|
- !ruby/object:Gem::Version
|
146
166
|
version: '3.3'
|
147
167
|
type: :development
|
148
168
|
prerelease: false
|
149
169
|
version_requirements: !ruby/object:Gem::Requirement
|
170
|
+
none: false
|
150
171
|
requirements:
|
151
|
-
- -
|
172
|
+
- - ~>
|
152
173
|
- !ruby/object:Gem::Version
|
153
174
|
version: '3.3'
|
154
175
|
- !ruby/object:Gem::Dependency
|
155
176
|
name: bunny
|
156
177
|
requirement: !ruby/object:Gem::Requirement
|
178
|
+
none: false
|
157
179
|
requirements:
|
158
|
-
- -
|
180
|
+
- - ~>
|
159
181
|
- !ruby/object:Gem::Version
|
160
182
|
version: '1.7'
|
161
183
|
type: :development
|
162
184
|
prerelease: false
|
163
185
|
version_requirements: !ruby/object:Gem::Requirement
|
186
|
+
none: false
|
164
187
|
requirements:
|
165
|
-
- -
|
188
|
+
- - ~>
|
166
189
|
- !ruby/object:Gem::Version
|
167
190
|
version: '1.7'
|
168
191
|
- !ruby/object:Gem::Dependency
|
169
192
|
name: timecop
|
170
193
|
requirement: !ruby/object:Gem::Requirement
|
194
|
+
none: false
|
171
195
|
requirements:
|
172
|
-
- -
|
196
|
+
- - ~>
|
173
197
|
- !ruby/object:Gem::Version
|
174
198
|
version: 0.7.1
|
175
199
|
type: :development
|
176
200
|
prerelease: false
|
177
201
|
version_requirements: !ruby/object:Gem::Requirement
|
202
|
+
none: false
|
178
203
|
requirements:
|
179
|
-
- -
|
204
|
+
- - ~>
|
180
205
|
- !ruby/object:Gem::Version
|
181
206
|
version: 0.7.1
|
182
207
|
- !ruby/object:Gem::Dependency
|
183
208
|
name: daemon_controller
|
184
209
|
requirement: !ruby/object:Gem::Requirement
|
210
|
+
none: false
|
185
211
|
requirements:
|
186
|
-
- -
|
212
|
+
- - ~>
|
187
213
|
- !ruby/object:Gem::Version
|
188
214
|
version: 1.2.0
|
189
215
|
type: :development
|
190
216
|
prerelease: false
|
191
217
|
version_requirements: !ruby/object:Gem::Requirement
|
218
|
+
none: false
|
192
219
|
requirements:
|
193
|
-
- -
|
220
|
+
- - ~>
|
194
221
|
- !ruby/object:Gem::Version
|
195
222
|
version: 1.2.0
|
196
223
|
description:
|
@@ -201,8 +228,8 @@ executables:
|
|
201
228
|
extensions: []
|
202
229
|
extra_rdoc_files: []
|
203
230
|
files:
|
204
|
-
-
|
205
|
-
-
|
231
|
+
- .gitignore
|
232
|
+
- .travis.yml
|
206
233
|
- CHANGELOG.md
|
207
234
|
- Gemfile
|
208
235
|
- LICENSE.txt
|
@@ -215,8 +242,9 @@ files:
|
|
215
242
|
- lib/emque/consuming/actor.rb
|
216
243
|
- lib/emque/consuming/adapter.rb
|
217
244
|
- lib/emque/consuming/adapters/rabbit_mq.rb
|
245
|
+
- lib/emque/consuming/adapters/rabbit_mq/delayed_message_worker.rb
|
246
|
+
- lib/emque/consuming/adapters/rabbit_mq/error_worker.rb
|
218
247
|
- lib/emque/consuming/adapters/rabbit_mq/manager.rb
|
219
|
-
- lib/emque/consuming/adapters/rabbit_mq/retry_worker.rb
|
220
248
|
- lib/emque/consuming/adapters/rabbit_mq/worker.rb
|
221
249
|
- lib/emque/consuming/application.rb
|
222
250
|
- lib/emque/consuming/cli.rb
|
@@ -237,6 +265,7 @@ files:
|
|
237
265
|
- lib/emque/consuming/logging.rb
|
238
266
|
- lib/emque/consuming/message.rb
|
239
267
|
- lib/emque/consuming/pidfile.rb
|
268
|
+
- lib/emque/consuming/retryable_errors.rb
|
240
269
|
- lib/emque/consuming/router.rb
|
241
270
|
- lib/emque/consuming/runner.rb
|
242
271
|
- lib/emque/consuming/status.rb
|
@@ -264,32 +293,34 @@ files:
|
|
264
293
|
- spec/dummy/config/routes.rb
|
265
294
|
- spec/error_tracker_spec.rb
|
266
295
|
- spec/pidfile_spec.rb
|
296
|
+
- spec/retryable_errors_spec.rb
|
267
297
|
- spec/router_spec.rb
|
268
298
|
- spec/runner_spec.rb
|
269
299
|
- spec/spec_helper.rb
|
270
300
|
homepage: https://github.com/teamsnap/emque-consuming
|
271
301
|
licenses:
|
272
302
|
- MIT
|
273
|
-
metadata: {}
|
274
303
|
post_install_message:
|
275
304
|
rdoc_options: []
|
276
305
|
require_paths:
|
277
306
|
- lib
|
278
307
|
required_ruby_version: !ruby/object:Gem::Requirement
|
308
|
+
none: false
|
279
309
|
requirements:
|
280
|
-
- -
|
310
|
+
- - ! '>='
|
281
311
|
- !ruby/object:Gem::Version
|
282
312
|
version: '2.1'
|
283
313
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
314
|
+
none: false
|
284
315
|
requirements:
|
285
|
-
- -
|
316
|
+
- - ! '>='
|
286
317
|
- !ruby/object:Gem::Version
|
287
318
|
version: '0'
|
288
319
|
requirements: []
|
289
320
|
rubyforge_project:
|
290
|
-
rubygems_version:
|
321
|
+
rubygems_version: 1.8.23
|
291
322
|
signing_key:
|
292
|
-
specification_version:
|
323
|
+
specification_version: 3
|
293
324
|
summary: Microservices framework for Ruby
|
294
325
|
test_files:
|
295
326
|
- spec/application_spec.rb
|
@@ -304,6 +335,7 @@ test_files:
|
|
304
335
|
- spec/dummy/config/routes.rb
|
305
336
|
- spec/error_tracker_spec.rb
|
306
337
|
- spec/pidfile_spec.rb
|
338
|
+
- spec/retryable_errors_spec.rb
|
307
339
|
- spec/router_spec.rb
|
308
340
|
- spec/runner_spec.rb
|
309
341
|
- spec/spec_helper.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 12f58267d541cb53c2dcd731663e1c19da52c801
|
4
|
-
data.tar.gz: c9555bff3fc2315e542cd637d4d2a4f387895169
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 9fce1adb82ccb832409b252e1ed3d2741fc80ae8e4706cac533bd594141915b10d98a3aacef168fc145e3f95170c3e9ef5675d402bad1a46b4651e069b4012fc
|
7
|
-
data.tar.gz: d0d287ed1519c23dcccc52bf9cc1dd3641af322d0ba1f47382a4fcc529321eb1251c714394bf3a5cf575d545bfc45d78dfad59b309683ae87dc907eb2f22c661
|