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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c9032fff24daef2ea6715eea71af92dd857df1ba
4
- data.tar.gz: 796b9f276b8c9a10cd8b00246bcd28f1c4ad3b9d
3
+ metadata.gz: b62e4d929c376e9f9cd7c5ca3d392cbd5e12bb4c
4
+ data.tar.gz: 768d2fd1ebe3ea28b79c2c44c7204117d6ae72ef
5
5
  SHA512:
6
- metadata.gz: 555b893cbe1b96557ec9f287031eee4862c68c6f65942996d2a70dc9e723ee89a3326354ce4fcd789a7dd8485964a893a27d2a135b13f84fc5da3e187c12c3e1
7
- data.tar.gz: 6c6f996560da05964ac20ae75afe5b402c0b7d3d79aa5cddf774ce2839030acde384b5012a51aedb339d2c6870c97ec1a4b431e7778ad632a3e9193b6f8efd85
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.3'
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"
@@ -1,3 +1,3 @@
1
1
  module LaGear
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
@@ -23,7 +23,7 @@ module LaGear
23
23
 
24
24
  module SneakersClassMethods
25
25
  def default_queue_name
26
- "#{Sneakers::Config.fetch(:app_name, 'sneakers_app').underscore}.#{routing_key}"
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::Config.fetch(:exchange, 'sneakers').underscore}.retry" }
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
@@ -6,6 +6,7 @@ require 'bunny'
6
6
 
7
7
  require 'sneakers'
8
8
  require 'sneakers/worker'
9
+ require "la_gear/sneakers"
9
10
  require 'la_gear/worker'
10
11
  require 'la_gear/publisher'
11
12
  require 'la_gear/bus'
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.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.3
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.3
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: '1.0'
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: '1.0'
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