la_gear 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|