la_gear 1.0.0 → 1.0.1
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/la_gear.gemspec +2 -2
- data/lib/la_gear/sneakers/exponential_backoff.rb +121 -0
- data/lib/la_gear/sneakers/exponential_backoff_handler.rb +39 -0
- data/lib/la_gear/sneakers.rb +1 -0
- data/lib/la_gear/version.rb +1 -1
- data/lib/la_gear/worker.rb +2 -2
- data/lib/la_gear.rb +1 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b62e4d929c376e9f9cd7c5ca3d392cbd5e12bb4c
|
4
|
+
data.tar.gz: 768d2fd1ebe3ea28b79c2c44c7204117d6ae72ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be2c62218f88ca5aa12080f6aacc453b52e87191ce4db8f2056a21239a269d01bc511bc1142d2beda7ce2127ba3cf1f29b6f09c18eab268ba2f7e436626a719e
|
7
|
+
data.tar.gz: dce9d6675fde75df927ee0a4307b30cf6eba2c3d2933b677254655e54d5b730f70d361419f2cafc4c7754f5abcf1c9d246d2ffe11c9a975f093ad833a6d6f225
|
data/la_gear.gemspec
CHANGED
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
spec.add_dependency 'json', '~> 1.8'
|
21
|
-
spec.add_dependency 'bunny', '~> 1.6
|
22
|
-
spec.add_dependency 'sneakers', '~> 1.0'
|
21
|
+
spec.add_dependency 'bunny', '~> 1.6'
|
22
|
+
spec.add_dependency 'sneakers', '~> 1.0.4'
|
23
23
|
spec.add_dependency 'activesupport', '~> 4.2'
|
24
24
|
spec.add_dependency 'sidekiq', '~> 3.3'
|
25
25
|
spec.add_dependency 'connection_pool', '~> 2.1'
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module LaGear
|
2
|
+
module Sneakers
|
3
|
+
module Handlers
|
4
|
+
class ExponentialBackoff
|
5
|
+
def initialize(channel, _queue, opts)
|
6
|
+
@channel = channel
|
7
|
+
@opts = opts
|
8
|
+
|
9
|
+
exchange = @opts.fetch(:exchange)
|
10
|
+
@handler_opts = @opts.fetch(:handler_opts, {})
|
11
|
+
|
12
|
+
retry_name = @handler_opts.fetch(:retryexchange, "#{exchange}.retry")
|
13
|
+
error_name = @handler_opts.fetch(:errorexchange, "#{exchange}.error")
|
14
|
+
|
15
|
+
@publish_channel = setup_publish_channel
|
16
|
+
@retry_exchange = setup_retry(@publish_channel, retry_name, exchange)
|
17
|
+
@error_exchange = setup_error(@publish_channel, error_name)
|
18
|
+
|
19
|
+
@max_retries = @handler_opts.fetch(:max_retries, 5)
|
20
|
+
@expiration = @handler_opts.fetch(:expiration, 1000)
|
21
|
+
end
|
22
|
+
|
23
|
+
def acknowledge(hdr)
|
24
|
+
@channel.acknowledge(hdr.delivery_tag, false)
|
25
|
+
end
|
26
|
+
|
27
|
+
def reject(hdr, props, msg, _requeue = false)
|
28
|
+
retry_or_error(hdr, props, msg, "rejected")
|
29
|
+
end
|
30
|
+
|
31
|
+
def error(hdr, props, msg, err)
|
32
|
+
retry_or_error(hdr, props, msg, err)
|
33
|
+
end
|
34
|
+
|
35
|
+
def timeout(hdr, props, msg)
|
36
|
+
error(hdr, props, msg, "Timeout: Sneakers worker timedout.")
|
37
|
+
end
|
38
|
+
|
39
|
+
def noop(_hdr); end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def retry_or_error(hdr, props, msg, reason, _requeue=false)
|
44
|
+
retries = get_retries(props[:headers])
|
45
|
+
if retries >= @max_retries
|
46
|
+
@error_exchange.publish(
|
47
|
+
msg,
|
48
|
+
routing_key: @handler_opts.fetch(:routing_key, hdr.routing_key),
|
49
|
+
headers: { "sneakers-error-reason" => (reason || "Doh! No reason given. :(").inspect }
|
50
|
+
)
|
51
|
+
else
|
52
|
+
expire_delay = get_expire_delay(retries)
|
53
|
+
|
54
|
+
@retry_exchange.publish(msg,
|
55
|
+
routing_key: @handler_opts.fetch(:routing_key, hdr.routing_key),
|
56
|
+
expiration: expire_delay,
|
57
|
+
headers: {
|
58
|
+
"sneakers-retries" => retries + 1,
|
59
|
+
"sneakers-retry-reason" => (reason || "Doh! No reason given.").inspect
|
60
|
+
})
|
61
|
+
end
|
62
|
+
@channel.acknowledge(hdr.delivery_tag, false)
|
63
|
+
rescue => e
|
64
|
+
logger.fatal "#{self} #{e}, hdr.routing_key #{hdr.routing_key}, props #{props}, msg #{msg}, reason #{reason}, handler_opts #{@handler_opts}, retries #{retries}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def setup_retry(publish_channel, retry_name, exchange)
|
68
|
+
retry_exchange = publish_channel.exchange(retry_name,
|
69
|
+
type: "topic",
|
70
|
+
durable: "true")
|
71
|
+
retry_queue = publish_channel.queue(retry_name,
|
72
|
+
durable: "true",
|
73
|
+
arguments: {
|
74
|
+
:"x-dead-letter-exchange" => exchange,
|
75
|
+
})
|
76
|
+
retry_queue.bind(retry_exchange, routing_key: "#")
|
77
|
+
trace(retry_queue, "#{self} retry queue created.")
|
78
|
+
retry_exchange
|
79
|
+
end
|
80
|
+
|
81
|
+
def setup_error(publish_channel, error_name)
|
82
|
+
error_exchange = publish_channel.exchange(error_name,
|
83
|
+
type: "topic",
|
84
|
+
durable: "true")
|
85
|
+
error_queue = publish_channel.queue(error_name, durable: "true")
|
86
|
+
error_queue.bind(error_exchange, routing_key: "#")
|
87
|
+
trace(error_queue, "#{self} error queue created.")
|
88
|
+
error_exchange
|
89
|
+
end
|
90
|
+
|
91
|
+
def setup_publish_channel
|
92
|
+
return @channel unless @opts.to_hash.include?(:amqp_publish)
|
93
|
+
publish_bunny = Bunny.new(@opts[:amqp_publish], vhost: @opts[:vhost], heartbeat: @opts[:heartbeat])
|
94
|
+
publish_bunny.start
|
95
|
+
publish_channel = publish_bunny.create_channel
|
96
|
+
publish_channel.prefetch(@opts[:prefetch])
|
97
|
+
logger.warn "#{self} publish endpoint used: #{@opts[:amqp_publish]}, vhost #{@opts[:vhost]}"
|
98
|
+
publish_channel
|
99
|
+
end
|
100
|
+
|
101
|
+
def trace(queue, msg)
|
102
|
+
logger.debug "[#{Thread.current}][#{queue.name}][#{queue.options}] #{msg}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def logger
|
106
|
+
::Sneakers.logger
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_expire_delay(failures = 0)
|
110
|
+
failures = failures.to_i + 1
|
111
|
+
@expiration * (2**failures)
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_retries(headers)
|
115
|
+
headers ||= {}
|
116
|
+
headers.fetch("sneakers-retries", 0).to_i
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
$: << File.expand_path('../lib', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'sneakers'
|
4
|
+
require 'sneakers/runner'
|
5
|
+
require_relative 'exponential_backoff'
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
Sneakers.configure(handler: LaGear::Sneakers::Handlers::ExponentialBackoff, workers: 1, threads: 1, prefetch: 1)
|
9
|
+
Sneakers.logger.level = Logger::INFO
|
10
|
+
|
11
|
+
class ExponentialBackoffWorker
|
12
|
+
include Sneakers::Worker
|
13
|
+
from_queue 'sneakers',
|
14
|
+
ack: true,
|
15
|
+
threads: 1,
|
16
|
+
prefetch: 1,
|
17
|
+
timeout_job_after: 60,
|
18
|
+
exchange: "sneakers",
|
19
|
+
heartbeat: 5,
|
20
|
+
arguments: {
|
21
|
+
:"x-dead-letter-exchange" => "sneakers-retry"
|
22
|
+
}
|
23
|
+
|
24
|
+
def work(msg)
|
25
|
+
puts "Got message #{msg} and rejecting now"
|
26
|
+
|
27
|
+
return reject!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
messages = 1
|
32
|
+
puts "Feeding messages in"
|
33
|
+
|
34
|
+
messages.times { ExponentialBackoffWorker.enqueue("{}") }
|
35
|
+
|
36
|
+
puts "Done"
|
37
|
+
|
38
|
+
r = Sneakers::Runner.new([ExponentialBackoffWorker])
|
39
|
+
r.run
|
@@ -0,0 +1 @@
|
|
1
|
+
require "la_gear/sneakers/exponential_backoff"
|
data/lib/la_gear/version.rb
CHANGED
data/lib/la_gear/worker.rb
CHANGED
@@ -23,7 +23,7 @@ module LaGear
|
|
23
23
|
|
24
24
|
module SneakersClassMethods
|
25
25
|
def default_queue_name
|
26
|
-
"#{Sneakers::
|
26
|
+
"#{Sneakers::CONFIG.fetch(:app_name, 'sneakers_app').underscore}.#{routing_key}"
|
27
27
|
end
|
28
28
|
|
29
29
|
def default_queue_opts
|
@@ -46,7 +46,7 @@ module LaGear
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def default_queue_args
|
49
|
-
{ 'x-dead-letter-exchange' => "#{Sneakers::
|
49
|
+
{ 'x-dead-letter-exchange' => "#{Sneakers::CONFIG.fetch(:exchange, 'sneakers').underscore}.retry" }
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
data/lib/la_gear.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: la_gear
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Chaney
|
@@ -32,28 +32,28 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 1.6
|
35
|
+
version: '1.6'
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 1.6
|
42
|
+
version: '1.6'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: sneakers
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 1.0.4
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: 1.0.4
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: activesupport
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -134,6 +134,9 @@ files:
|
|
134
134
|
- lib/la_gear/bus.rb
|
135
135
|
- lib/la_gear/engine.rb
|
136
136
|
- lib/la_gear/publisher.rb
|
137
|
+
- lib/la_gear/sneakers.rb
|
138
|
+
- lib/la_gear/sneakers/exponential_backoff.rb
|
139
|
+
- lib/la_gear/sneakers/exponential_backoff_handler.rb
|
137
140
|
- lib/la_gear/sneakers_configurer.rb
|
138
141
|
- lib/la_gear/uri_parser.rb
|
139
142
|
- lib/la_gear/version.rb
|