rails_autoscale_agent 0.9.0.beta.1 → 0.9.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
  SHA256:
3
- metadata.gz: 37ecb709c866b3d831f79d8a15bd54cfcacfd00dc45ebf84ad5129c0d1206a3d
4
- data.tar.gz: 373474c8d84bb5cbd026f792aef4eef4028d77b666d74ac4407cd7d4c603703d
3
+ metadata.gz: 2cfb11be1fd0dcc95dff095c62bf485e99f3a3f89ece5ce86def57877d6c72bd
4
+ data.tar.gz: 0e08106bd9c2956c9bfb231b122e69805530fd6641d79cc796d02c7766558270
5
5
  SHA512:
6
- metadata.gz: cbe7b97077c907d45deba6cfa0dce814e8d5fff2339cdf8c81c7e96101d0e3cd8a1dcbcdd3474bcb8fe798ec7591f59b040a8e40d367fa11b32c4dbd6ead52f1
7
- data.tar.gz: 2677393fb16bb0fb776c2325838074ed3c0c9c4d990d296e950ad83576456ac66b15765a96e84a1fefe26ff6696ca89e419e23db78a644e01054378c7dbf3cd1
6
+ metadata.gz: 9f3b58a566a6c0119f33c23d4a3f986c20269697b328e1f58af487f305f2e76534afe05027fa5f45ad3b64d6a8ad1afbb7160fe679d009a9f6af40ee8714a3f9
7
+ data.tar.gz: 3ceea68c551175a2760b2fc539f95dca0a15695f94d151590d84626c376b77b566db700d239370c8f5935eaf5b95f40ef4599fdf193a147f47cc0a84ffe152c6
@@ -6,7 +6,8 @@
6
6
  {
7
7
  "label": "test: all",
8
8
  "group": "test",
9
- "command": "rspec",
9
+ "command": "bundle",
10
+ "args": ["exec", "rspec"],
10
11
  "runOptions": {
11
12
  "reevaluateOnRerun": false
12
13
  },
@@ -31,8 +32,8 @@
31
32
  {
32
33
  "label": "test: file",
33
34
  "group": "test",
34
- "command": "rspec",
35
- "args": ["${relativeFile}"],
35
+ "command": "bundle",
36
+ "args": ["exec", "rspec", "${relativeFile}"],
36
37
  "runOptions": {
37
38
  "reevaluateOnRerun": false
38
39
  },
@@ -57,8 +58,8 @@
57
58
  {
58
59
  "label": "test: line",
59
60
  "group": "test",
60
- "command": "rspec",
61
- "args": ["${relativeFile}:${lineNumber}"],
61
+ "command": "bundle",
62
+ "args": ["exec", "rspec", "${relativeFile}:${lineNumber}"],
62
63
  "runOptions": {
63
64
  "reevaluateOnRerun": false
64
65
  },
data/Gemfile CHANGED
@@ -1,4 +1,16 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in rails_autoscale_agent.gemspec
4
3
  gemspec
4
+
5
+ gem "rake", ">= 12.3.3"
6
+ gem "rspec", ">= 3.0"
7
+ gem "vcr", ">= 3.0"
8
+ gem "webmock"
9
+ gem "pry-byebug"
10
+ gem "sidekiq", ">= 5.0"
11
+ gem "delayed_job"
12
+ gem "delayed_job_active_record"
13
+ gem "que"
14
+ gem "resque"
15
+ gem "activesupport"
16
+ gem "sqlite3", platforms: :ruby
data/README.md CHANGED
@@ -24,16 +24,6 @@ The agent will only communicate with Rails Autoscale if a `RAILS_AUTOSCALE_URL`
24
24
 
25
25
  You'll need to insert the `RailsAutoscaleAgent::Middleware` manually. Insert it before `Rack::Runtime` to ensure accuracy of request queue timings.
26
26
 
27
- ## Changing the logger
28
-
29
- The Rails logger is used by default.
30
- If you wish to use a different logger you can set it on the configuration object:
31
-
32
- ```ruby
33
- # config/initializers/rails_autoscale_agent.rb
34
- RailsAutoscaleAgent::Config.instance.logger = MyLogger.new
35
- ```
36
-
37
27
  ## What data is collected?
38
28
 
39
29
  The middleware agent runs in its own thread so your web requests are not impacted. The following data is submitted periodically to the Rails Autoscale API:
@@ -59,17 +49,39 @@ In production, run `heroku logs -t | grep RailsAutoscale`, and you should see so
59
49
 
60
50
  If you don't see either of these, try running `bundle` again and restarting your Rails application.
61
51
 
62
- You can see more detailed (debug) logging by setting the `RAILS_AUTOSCALE_DEBUG` env var on your Heroku app:
52
+ You can see more detailed (debug) logging by setting `RAILS_AUTOSCALE_DEBUG` on your Heroku app:
63
53
 
64
54
  ```
65
55
  heroku config:add RAILS_AUTOSCALE_DEBUG=true
66
56
  ```
67
57
 
68
- Debug logs are silenced by default because Rails apps default to a DEBUG log level in production,
69
- and these can get very noisy with this gem.
58
+ See more in the [logging](#logging) section below.
70
59
 
71
60
  Reach out to help@railsautoscale.com if you run into any other problems.
72
61
 
62
+ ## Logging
63
+
64
+ The Rails logger is used by default.
65
+ If you wish to use a different logger you can set it on the configuration object:
66
+
67
+ ```ruby
68
+ # config/initializers/rails_autoscale_agent.rb
69
+ RailsAutoscaleAgent::Config.instance.logger = MyLogger.new
70
+ ```
71
+
72
+ Debug logs are silenced by default because Rails apps default to a DEBUG log level in production, and this gem has _very_ chatty debug logs. If you want to see the debug logs, set `RAILS_AUTOSCALE_DEBUG` on your Heroku app:
73
+
74
+ ```
75
+ heroku config:add RAILS_AUTOSCALE_DEBUG=true
76
+ ```
77
+
78
+ If you find the gem too chatty even without this, you can quiet it down further:
79
+
80
+ ```ruby
81
+ # config/initializers/rails_autoscale_agent.rb
82
+ RailsAutoscaleAgent::Config.instance.quiet = true
83
+ ```
84
+
73
85
  ## Development
74
86
 
75
87
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -24,6 +24,10 @@ module RailsAutoscaleAgent
24
24
  post_json '/registrations', registration: registration_params
25
25
  end
26
26
 
27
+ def report_exception!(ex)
28
+ post_json '/exceptions', message: ex.inspect, backtrace: ex.backtrace.join("\n")
29
+ end
30
+
27
31
  private
28
32
 
29
33
  def post_json(path, data)
@@ -7,7 +7,7 @@ module RailsAutoscaleAgent
7
7
  include Singleton
8
8
 
9
9
  attr_accessor :report_interval, :logger, :api_base_url, :max_request_size,
10
- :dyno, :pid, :addon_name, :worker_adapters, :dev_mode
10
+ :dyno, :pid, :addon_name, :worker_adapters, :dev_mode, :debug, :quiet
11
11
 
12
12
  def initialize
13
13
  require 'rails_autoscale_agent/worker_adapters/sidekiq'
@@ -25,11 +25,12 @@ module RailsAutoscaleAgent
25
25
  @addon_name = ENV['RAILS_AUTOSCALE_ADDON'] || 'RAILS_AUTOSCALE'
26
26
  @api_base_url = ENV["#{@addon_name}_URL"]
27
27
  @dev_mode = ENV['RAILS_AUTOSCALE_DEV'] == 'true'
28
+ @debug = dev_mode? || ENV['RAILS_AUTOSCALE_DEBUG'] == 'true'
28
29
  @pid = Process.pid
29
30
  @max_request_size = 100_000 # ignore request payloads over 100k since they skew the queue times
30
31
  @report_interval = 10 # this default will be overwritten during Reporter#register!
31
32
  @logger ||= defined?(Rails) ? Rails.logger : ::Logger.new(STDOUT)
32
- @dyno = @dev_mode ? 'dev.1' : ENV['DYNO']
33
+ @dyno = dev_mode? ? 'dev.1' : ENV['DYNO']
33
34
  end
34
35
 
35
36
  def to_s
@@ -41,5 +42,7 @@ module RailsAutoscaleAgent
41
42
  end
42
43
 
43
44
  alias_method :dev_mode?, :dev_mode
45
+ alias_method :debug?, :debug
46
+ alias_method :quiet?, :quiet
44
47
  end
45
48
  end
@@ -13,26 +13,33 @@ module RailsAutoscaleAgent
13
13
  class LoggerProxy < Struct.new(:logger)
14
14
  TAG = '[RailsAutoscale]'
15
15
 
16
- %w[info warn error].each do |name|
17
- define_method name do |msg|
18
- logger.send name, tag(msg)
19
- end
16
+ def error(msg)
17
+ logger.error tag(msg)
18
+ end
19
+
20
+ def warn(msg)
21
+ logger.warn tag(msg)
22
+ end
23
+
24
+ def info(msg)
25
+ logger.info tag(msg) unless Config.instance.quiet?
20
26
  end
21
27
 
22
28
  def debug(msg)
23
29
  # Silence debug logs by default to avoiding being overly chatty (Rails logger defaults
24
- # to DEBUG level in production).
25
- # This uses a separate logger so that RAILS_AUTOSCALE_DEBUG
26
- # shows debug logs regardless of Rails log level.
27
- debug_logger.debug tag(msg) if ENV['RAILS_AUTOSCALE_DEBUG'] == 'true' || Config.instance.dev_mode?
30
+ # to DEBUG level in production). Setting RAILS_AUTOSCALE_DEBUG=true enables debug logs,
31
+ # even if the underlying logger severity level is INFO.
32
+ if Config.instance.debug?
33
+ if logger.respond_to?(:debug?) && logger.debug?
34
+ logger.debug tag(msg)
35
+ elsif logger.respond_to?(:info?) && logger.info?
36
+ logger.info tag("[DEBUG] #{msg}")
37
+ end
38
+ end
28
39
  end
29
40
 
30
41
  private
31
42
 
32
- def debug_logger
33
- @debug_loggers ||= ::Logger.new(STDOUT)
34
- end
35
-
36
43
  def tag(msg)
37
44
  "#{TAG} #{msg}"
38
45
  end
@@ -41,7 +41,7 @@ module RailsAutoscaleAgent
41
41
  # Exceptions in threads other than the main thread will fail silently
42
42
  # https://ruby-doc.org/core-2.2.0/Thread.html#class-Thread-label-Exception+handling
43
43
  logger.error "Reporter error: #{ex.inspect}"
44
- logger.error ex.backtrace.join("\n")
44
+ AutoscaleApi.new(config).report_exception!(ex)
45
45
  end
46
46
  end
47
47
  end
@@ -4,20 +4,17 @@ module RailsAutoscaleAgent
4
4
  class Request
5
5
  include Logger
6
6
 
7
- attr_reader :id, :entered_queue_at, :path, :method, :size
8
-
9
7
  def initialize(env, config)
10
8
  @config = config
11
9
  @id = env['HTTP_X_REQUEST_ID']
12
- @path = env['PATH_INFO']
13
- @method = env['REQUEST_METHOD'].downcase
14
10
  @size = env['rack.input'].respond_to?(:size) ? env['rack.input'].size : 0
11
+ @request_body_wait = env['puma.request_body_wait'].to_i
15
12
 
16
13
  @entered_queue_at = if unix_millis = env['HTTP_X_REQUEST_START']
17
14
  Time.at(unix_millis.to_f / 1000)
18
15
  elsif config.dev_mode?
19
16
  # In dev mode, fake a queue time of 0-1000ms
20
- Time.now - rand
17
+ Time.now - rand + @request_body_wait
21
18
  end
22
19
  end
23
20
 
@@ -26,12 +23,17 @@ module RailsAutoscaleAgent
26
23
  end
27
24
 
28
25
  def queue_time
29
- if entered_queue_at
30
- queue_time = ((Time.now - entered_queue_at) * 1000).to_i
31
- queue_time = 0 if queue_time < 0
32
- logger.debug "Collected queue_time=#{queue_time}ms request_id=#{id} request_size=#{size}"
26
+ if @entered_queue_at
27
+ queue_time = ((Time.now - @entered_queue_at) * 1000).to_i
28
+
29
+ # Subtract the time Puma spent waiting on the request body. It's irrelevant to capacity-related queue time.
30
+ # Without this, slow clients and large request payloads will skew queue time.
31
+ queue_time -= @request_body_wait
32
+
33
+ logger.debug "Request queue_time=#{queue_time}ms body_wait=#{@request_body_wait}ms request_id=#{@id} size=#{@size}"
33
34
 
34
- queue_time
35
+ # Safeguard against negative queue times (should not happen in practice)
36
+ queue_time > 0 ? queue_time : 0
35
37
  end
36
38
  end
37
39
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAutoscaleAgent
4
- VERSION = "0.9.0.beta.1"
4
+ VERSION = "0.9.1"
5
5
  end
@@ -8,58 +8,50 @@ module RailsAutoscaleAgent
8
8
  include RailsAutoscaleAgent::Logger
9
9
  include Singleton
10
10
 
11
- class << self
12
- attr_accessor :queues
13
- end
11
+ attr_writer :queues
14
12
 
15
- def initialize
13
+ def queues
16
14
  # Track the known queues so we can continue reporting on queues that don't
17
- # currently have enqueued jobs.
18
- self.class.queues = Set.new
19
-
20
- install if enabled?
15
+ # have enqueued jobs at the time of reporting.
16
+ # Assume a "default" queue so we always report *something*, even when nothing
17
+ # is enqueued.
18
+ @queues ||= Set.new(['default'])
21
19
  end
22
20
 
23
21
  def enabled?
24
- defined? ::Delayed
22
+ if defined?(::Delayed::Job) && defined?(::Delayed::Backend::ActiveRecord)
23
+ logger.info "DelayedJob enabled (#{::ActiveRecord::Base.default_timezone})"
24
+ true
25
+ end
25
26
  end
26
27
 
27
28
  def collect!(store)
28
29
  log_msg = String.new
29
- t = Time.now
30
+ t = Time.now.utc
31
+ sql = <<~SQL
32
+ SELECT COALESCE(queue, 'default'), min(run_at)
33
+ FROM delayed_jobs
34
+ WHERE locked_at IS NULL
35
+ AND failed_at IS NULL
36
+ GROUP BY queue
37
+ SQL
30
38
 
31
- sql = 'SELECT queue, min(run_at) FROM delayed_jobs GROUP BY queue'
32
39
  run_at_by_queue = Hash[ActiveRecord::Base.connection.select_rows(sql)]
33
- queues = self.class.queues | run_at_by_queue.keys
40
+ self.queues |= run_at_by_queue.keys
34
41
 
35
42
  queues.each do |queue|
36
- next if queue.nil? || queue.empty?
37
43
  run_at = run_at_by_queue[queue]
38
- run_at = Time.parse(run_at) if run_at.is_a?(String)
44
+ # DateTime.parse assumes a UTC string
45
+ run_at = DateTime.parse(run_at) if run_at.is_a?(String)
39
46
  latency_ms = run_at ? ((t - run_at)*1000).ceil : 0
47
+ latency_ms = 0 if latency_ms < 0
48
+
40
49
  store.push latency_ms, t, queue
41
50
  log_msg << "dj.#{queue}=#{latency_ms} "
42
51
  end
43
52
 
44
53
  logger.debug log_msg unless log_msg.empty?
45
54
  end
46
-
47
- private
48
-
49
- def install
50
- plugin = Class.new(Delayed::Plugin) do
51
- require 'delayed_job'
52
-
53
- callbacks do |lifecycle|
54
- lifecycle.before(:enqueue) do |job, &block|
55
- queue = job.queue || 'default'
56
- WorkerAdapters::DelayedJob.queues.add queue
57
- end
58
- end
59
- end
60
-
61
- Delayed::Worker.plugins << plugin
62
- end
63
55
  end
64
56
  end
65
57
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rails_autoscale_agent/logger'
4
- require 'time'
5
4
 
6
5
  module RailsAutoscaleAgent
7
6
  module WorkerAdapters
@@ -9,34 +8,44 @@ module RailsAutoscaleAgent
9
8
  include RailsAutoscaleAgent::Logger
10
9
  include Singleton
11
10
 
12
- DEFAULT_QUEUES = ['default']
11
+ attr_writer :queues
13
12
 
14
- class << self
15
- attr_accessor :queues
16
- end
17
-
18
- def initialize
19
- self.class.queues = DEFAULT_QUEUES
13
+ def queues
14
+ # Track the known queues so we can continue reporting on queues that don't
15
+ # have enqueued jobs at the time of reporting.
16
+ # Assume a "default" queue so we always report *something*, even when nothing
17
+ # is enqueued.
18
+ @queues ||= Set.new(['default'])
20
19
  end
21
20
 
22
21
  def enabled?
23
- defined? ::Que
22
+ if defined?(::Que)
23
+ logger.info "Que enabled (#{::ActiveRecord::Base.default_timezone})"
24
+ true
25
+ end
24
26
  end
25
27
 
26
28
  def collect!(store)
27
29
  log_msg = String.new
28
- t = Time.now
30
+ t = Time.now.utc
31
+ sql = <<~SQL
32
+ SELECT queue, min(run_at)
33
+ FROM que_jobs
34
+ WHERE finished_at IS NULL
35
+ AND expired_at IS NULL
36
+ AND error_count = 0
37
+ GROUP BY 1
38
+ SQL
29
39
 
30
- # Ignore failed jobs (they skew latency measurement due to the original run_at)
31
- sql = 'SELECT queue, min(run_at) FROM que_jobs WHERE error_count = 0 GROUP BY queue'
32
40
  run_at_by_queue = Hash[ActiveRecord::Base.connection.select_rows(sql)]
33
- self.class.queues |= run_at_by_queue.keys
41
+ self.queues |= run_at_by_queue.keys
34
42
 
35
- self.class.queues.each do |queue|
36
- next if queue.nil? || queue.empty?
43
+ queues.each do |queue|
37
44
  run_at = run_at_by_queue[queue]
38
- run_at = Time.parse(run_at) if run_at.is_a?(String)
45
+ run_at = DateTime.parse(run_at) if run_at.is_a?(String)
39
46
  latency_ms = run_at ? ((t - run_at)*1000).ceil : 0
47
+ latency_ms = 0 if latency_ms < 0
48
+
40
49
  store.push latency_ms, t, queue
41
50
  log_msg << "que.#{queue}=#{latency_ms} "
42
51
  end
@@ -8,8 +8,15 @@ module RailsAutoscaleAgent
8
8
  include RailsAutoscaleAgent::Logger
9
9
  include Singleton
10
10
 
11
+ attr_writer :queues
12
+
13
+ def queues
14
+ @queues ||= ['default']
15
+ end
16
+
11
17
  def enabled?
12
18
  require 'resque'
19
+ logger.info "Resque enabled"
13
20
  true
14
21
  rescue LoadError
15
22
  false
@@ -18,7 +25,11 @@ module RailsAutoscaleAgent
18
25
  def collect!(store)
19
26
  log_msg = String.new
20
27
 
21
- ::Resque.queues.each do |queue|
28
+ # Ensure we continue to collect metrics for known queue names, even when nothing is
29
+ # enqueued at the time. Without this, it will appears that the agent is no longer reporting.
30
+ self.queues |= ::Resque.queues
31
+
32
+ queues.each do |queue|
22
33
  next if queue.nil? || queue.empty?
23
34
  depth = ::Resque.size(queue)
24
35
  store.push depth, Time.now, queue, :qd
@@ -8,8 +8,15 @@ module RailsAutoscaleAgent
8
8
  include RailsAutoscaleAgent::Logger
9
9
  include Singleton
10
10
 
11
+ attr_writer :known_queue_names
12
+
13
+ def known_queue_names
14
+ @known_queue_names ||= ['default']
15
+ end
16
+
11
17
  def enabled?
12
18
  require 'sidekiq/api'
19
+ logger.info "Sidekiq enabled"
13
20
  true
14
21
  rescue LoadError
15
22
  false
@@ -17,8 +24,18 @@ module RailsAutoscaleAgent
17
24
 
18
25
  def collect!(store)
19
26
  log_msg = String.new
27
+ queues_by_name = ::Sidekiq::Queue.all.each_with_object({}) do |queue, obj|
28
+ obj[queue.name] = queue
29
+ end
30
+
31
+ # Ensure we continue to collect metrics for known queue names, even when nothing is
32
+ # enqueued at the time. Without this, it will appears that the agent is no longer reporting.
33
+ known_queue_names.each do |queue_name|
34
+ queues_by_name[queue_name] ||= ::Sidekiq::Queue.new(queue_name)
35
+ end
36
+ self.known_queue_names = queues_by_name.keys
20
37
 
21
- ::Sidekiq::Queue.all.each do |queue|
38
+ queues_by_name.each do |queue_name, queue|
22
39
  latency_ms = (queue.latency * 1000).ceil
23
40
  depth = queue.size
24
41
  store.push latency_ms, Time.now, queue.name, :qt
@@ -15,16 +15,4 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
17
  spec.require_paths = ["lib"]
18
-
19
- spec.add_development_dependency "bundler", "~> 2.0"
20
- spec.add_development_dependency "rake", "~> 12.3.3"
21
- spec.add_development_dependency "rspec", "~> 3.0"
22
- spec.add_development_dependency "vcr", "~> 3.0"
23
- spec.add_development_dependency "webmock"
24
- spec.add_development_dependency "pry"
25
- spec.add_development_dependency "pry-byebug"
26
- spec.add_development_dependency "sidekiq", "~> 5.0"
27
- spec.add_development_dependency "delayed_job"
28
- spec.add_development_dependency "que"
29
- spec.add_development_dependency "activesupport"
30
18
  end
metadata CHANGED
@@ -1,169 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_autoscale_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0.beta.1
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam McCrea
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-20 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '2.0'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 12.3.3
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 12.3.3
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: vcr
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '3.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '3.0'
69
- - !ruby/object:Gem::Dependency
70
- name: webmock
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: pry
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: pry-byebug
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: sidekiq
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '5.0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '5.0'
125
- - !ruby/object:Gem::Dependency
126
- name: delayed_job
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: que
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: activesupport
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
11
+ date: 2020-07-29 00:00:00.000000000 Z
12
+ dependencies: []
167
13
  description:
168
14
  email:
169
15
  - adam@adamlogic.com
@@ -217,11 +63,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
217
63
  version: '0'
218
64
  required_rubygems_version: !ruby/object:Gem::Requirement
219
65
  requirements:
220
- - - ">"
66
+ - - ">="
221
67
  - !ruby/object:Gem::Version
222
- version: 1.3.1
68
+ version: '0'
223
69
  requirements: []
224
- rubygems_version: 3.0.3
70
+ rubygems_version: 3.1.4
225
71
  signing_key:
226
72
  specification_version: 4
227
73
  summary: This gem works with the Rails Autoscale Heroku add-on to automatically scale