rails_autoscale_agent 0.9.0.beta.2 → 0.10.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/.vscode/tasks.json +6 -5
- data/CHANGELOG.md +109 -0
- data/Gemfile +13 -1
- data/README.md +52 -14
- data/lib/rails_autoscale_agent/autoscale_api.rb +1 -1
- data/lib/rails_autoscale_agent/config.rb +25 -14
- data/lib/rails_autoscale_agent/logger.rb +19 -12
- data/lib/rails_autoscale_agent/registration.rb +1 -1
- data/lib/rails_autoscale_agent/report.rb +1 -1
- data/lib/rails_autoscale_agent/reporter.rb +25 -8
- data/lib/rails_autoscale_agent/request.rb +25 -16
- data/lib/rails_autoscale_agent/store.rb +5 -0
- data/lib/rails_autoscale_agent/version.rb +1 -1
- data/lib/rails_autoscale_agent/worker_adapters/delayed_job.rb +62 -31
- data/lib/rails_autoscale_agent/worker_adapters/que.rb +40 -17
- data/lib/rails_autoscale_agent/worker_adapters/resque.rb +19 -1
- data/lib/rails_autoscale_agent/worker_adapters/sidekiq.rb +48 -1
- data/rails_autoscale_agent.gemspec +1 -11
- metadata +13 -166
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed5e9567b63e205a9477e80cb3b1cb5d0d198f60288957c8560eb988f0ab5322
|
4
|
+
data.tar.gz: 0ff58213c0347a71218c668fbcea5f3bae8e6e24701b7c9ce3317d84dfce8ef7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3da81efface83a93ac9c3676b7edbcaf431911cfe428c054a39203663048bc7a320ebd6881606d7b18e563c145d8fcfc1cd6d3acf945bff82525195796f1be96
|
7
|
+
data.tar.gz: a4012e4ab5876cddb28bfea34a2b71d6239c34dc5b167cb54616e5635a67d36915245c2b96bc536256ee7109640db6a035d0b5b99bfa20fab76a88900aba6f3f
|
data/.vscode/tasks.json
CHANGED
@@ -6,7 +6,8 @@
|
|
6
6
|
{
|
7
7
|
"label": "test: all",
|
8
8
|
"group": "test",
|
9
|
-
"command": "
|
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": "
|
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": "
|
61
|
-
"args": ["${relativeFile}:${lineNumber}"],
|
61
|
+
"command": "bundle",
|
62
|
+
"args": ["exec", "rspec", "${relativeFile}:${lineNumber}"],
|
62
63
|
"runOptions": {
|
63
64
|
"reevaluateOnRerun": false
|
64
65
|
},
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
2
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
3
|
+
|
4
|
+
## [Unreleased](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.10.1...master)
|
5
|
+
|
6
|
+
_There are no currently unreleased changes._
|
7
|
+
|
8
|
+
## [0.10.1](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.9.1...v0.10.1) - 2021-01-03
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Add support for [long-running jobs](https://railsautoscale.com/docs/long-running-jobs/) in Sidekiq and Delayed Job.
|
13
|
+
- Handle x-request-start measured in seconds (instead of milliseconds) to support nginx buildpack ([cd092f3](https://github.com/adamlogic/rails_autoscale_agent/commit/cd092f38718abf5ffaea866bcae7831d4c910ffd))
|
14
|
+
- Override worker adapter config via env var ([75dd06b](https://github.com/adamlogic/rails_autoscale_agent/commit/75dd06b2a7ff4eeab829eec24d503dc067c8fe32))
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
- Require Ruby 2.5 or newer. ([b033050](https://github.com/adamlogic/rails_autoscale_agent/commit/b033050b7f9d4d7f1e50dbd780cf0e1822249268))
|
19
|
+
- Only report worker metrics from web.1 to avoid redundant data. ([d5d5fa8](https://github.com/adamlogic/rails_autoscale_agent/commit/d5d5fa87fb4d7d046832a64edde9ed0c3a6ec75f))
|
20
|
+
- Don't collect worker metrics for an unreasonable number of queues. ([a9358af](https://github.com/adamlogic/rails_autoscale_agent/commit/a9358af74a29a941d1f1d60a0222077dafd5ce08))
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
|
24
|
+
- Avoid holding onto database connections (DJ & Que only). ([3919ca5](https://github.com/adamlogic/rails_autoscale_agent/commit/3919ca54420cafa82abf9f8cd251569f9637482b))
|
25
|
+
- Better error handling for worker adapters. ([190786e](https://github.com/adamlogic/rails_autoscale_agent/commit/190786e4a910d41e394a3129aac1d23b594dbd9b))
|
26
|
+
- Don't collect metrics of the reporter isn't running. Avoids memory bloat. ([247c322](https://github.com/adamlogic/rails_autoscale_agent/commit/247c322cffc625a8c6b2395080a048ffb94e7f3b))
|
27
|
+
|
28
|
+
## [0.10.0](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.9.1...v0.10.0) - 2021-01-03 [YANKED]
|
29
|
+
|
30
|
+
_I released the wrong branch 🤦♂️_
|
31
|
+
|
32
|
+
## [0.9.1](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.9.0...v0.9.1) - 2020-07-29
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
|
36
|
+
- Fix a bug in error handling. ([3018542](https://github.com/adamlogic/rails_autoscale_agent/commit/3018542cd046fc4e1bd6e7da86e72a6aa2d50a8f))
|
37
|
+
- Remove unintentional Rails dependency.
|
38
|
+
|
39
|
+
## [0.9.0](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.8.3...v0.9.0) - 2020-07-12
|
40
|
+
|
41
|
+
### Added
|
42
|
+
|
43
|
+
- Add support for Resque workers.
|
44
|
+
- Add dev mode for working on the agent gem itself. ([47e3fca](https://github.com/adamlogic/rails_autoscale_agent/commit/47e3fca5b788f48567a345d9cab3a26b9cd87693))
|
45
|
+
- Report agent exceptions to Rails Autoscale.
|
46
|
+
|
47
|
+
### Changed
|
48
|
+
|
49
|
+
- Adjust queue time metric to exclude time waiting for large request bodies. ([#25](https://github.com/adamlogic/rails_autoscale_agent/pull/25))
|
50
|
+
- Que and DJ jobs without a queue name will be included in the "default" queue metrics.
|
51
|
+
|
52
|
+
### Fixed
|
53
|
+
|
54
|
+
- Multiple fixes to the Delayed Job SQL query.
|
55
|
+
|
56
|
+
## [0.8.3](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.8.2...v0.8.3) - 2020-05-26
|
57
|
+
|
58
|
+
### Fixed
|
59
|
+
|
60
|
+
- Ignored failed job in Delayed Job adapter. ([fa72fc2](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.8.2...v0.8.3))
|
61
|
+
|
62
|
+
## [0.8.2](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.8.1...v0.8.2) - 2020-05-22
|
63
|
+
|
64
|
+
### Fixed
|
65
|
+
|
66
|
+
- Ignore worker metrics from unnamed queues (DJ & Que only). These metrics were being lumped with web metrics. ([#21](https://github.com/adamlogic/rails_autoscale_agent/pull/21))
|
67
|
+
|
68
|
+
## [0.8.1](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.8.0...v0.8.1) - 2020-05-04
|
69
|
+
|
70
|
+
### Fixed
|
71
|
+
|
72
|
+
- Ignore failed jobs in Que adapter. ([#18](https://github.com/adamlogic/rails_autoscale_agent/pull/18))
|
73
|
+
|
74
|
+
## [0.8.0](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.7.0...v0.8.0) - 2020-03-21
|
75
|
+
|
76
|
+
### Added
|
77
|
+
|
78
|
+
- Add support for Delayed Job ([#14](https://github.com/adamlogic/rails_autoscale_agent/pull/14))
|
79
|
+
- Add support for Que ([#15](https://github.com/adamlogic/rails_autoscale_agent/pull/15))
|
80
|
+
|
81
|
+
## [0.7.0](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.6.3...v0.7.0) - 2019-12-04
|
82
|
+
|
83
|
+
### Added
|
84
|
+
|
85
|
+
- Make worker adapters configurable. ([012d937](https://github.com/adamlogic/rails_autoscale_agent/commit/012d9379296763f5e42df95f05b066fe82ab0051))
|
86
|
+
|
87
|
+
## [0.6.3](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.6.2...v0.6.3) - 2019-06-25
|
88
|
+
|
89
|
+
### Fixed
|
90
|
+
|
91
|
+
- Fix issues with logging.
|
92
|
+
|
93
|
+
## [0.6.2](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.6.1...v0.6.2) - 2019-06-22
|
94
|
+
|
95
|
+
### Fixed
|
96
|
+
|
97
|
+
- Fix issues with logging.
|
98
|
+
|
99
|
+
## [0.6.1](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.6.0...v0.6.1) - 2019-05-06
|
100
|
+
|
101
|
+
### Fixed
|
102
|
+
|
103
|
+
- Don't assume Sidekiq is present.
|
104
|
+
|
105
|
+
## [0.6.0](https://github.com/adamlogic/rails_autoscale_agent/compare/v0.4.1...v0.6.0) - 2019-05-03
|
106
|
+
|
107
|
+
### Added
|
108
|
+
|
109
|
+
- Add support for autoscaling Sidekiq.
|
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
@@ -22,17 +22,7 @@ The agent will only communicate with Rails Autoscale if a `RAILS_AUTOSCALE_URL`
|
|
22
22
|
|
23
23
|
## Non-Rails Rack apps
|
24
24
|
|
25
|
-
You'll need to insert the `RailsAutoscaleAgent::Middleware` manually. Insert it before `Rack::Runtime` to ensure accuracy of request queue timings.
|
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
|
-
```
|
25
|
+
You'll need to `require 'rails_autoscale_agent/middleware'` and insert the `RailsAutoscaleAgent::Middleware` manually. Insert it before `Rack::Runtime` to ensure accuracy of request queue timings.
|
36
26
|
|
37
27
|
## What data is collected?
|
38
28
|
|
@@ -47,6 +37,32 @@ The middleware agent runs in its own thread so your web requests are not impacte
|
|
47
37
|
|
48
38
|
Rails Autoscale aggregates and stores this information to power the autoscaling algorithm and dashboard visualizations.
|
49
39
|
|
40
|
+
## Configuration
|
41
|
+
|
42
|
+
Most Rails Autoscale configurations are handled via the settings page on your Rails Autoscale dashboard, but there a few ways you can directly change the behavior of the agent via environment variables:
|
43
|
+
|
44
|
+
- `RAILS_AUTOSCALE_DEBUG` - Enables debug logging. See more in the [logging](#logging) section below.
|
45
|
+
- `RAILS_AUTOSCALE_WORKER_ADAPTER` - Overrides the available worker adapters. See more in the [worker adapters](#worker_adapters) section below.
|
46
|
+
- `RAILS_AUTOSCALE_LONG_JOBS` - Enables reporting for active workers. See [Handling Long-Running Background Jobs](https://railsautoscale.com/docs/long-running-jobs/) in the Rails Autoscale docs for more.
|
47
|
+
|
48
|
+
## Worker adapters
|
49
|
+
|
50
|
+
Rails Autoscale supports autoscaling worker dynos. Out of the box, four job backends are supported: Sidekiq, Resque, Delayed Job, and Que. The agent will automatically enable the appropriate worker adapter based on what you have installed in your app.
|
51
|
+
|
52
|
+
In some scenarios you might want to override this behavior. Let's say you have both Sidekiq and Resque installed 🤷♂️, but you only want Rails Autoscale to collect metrics for Sidekiq. Here's how you'd override that:
|
53
|
+
|
54
|
+
```
|
55
|
+
heroku config:add RAILS_AUTOSCALE_WORKER_ADAPTER=sidekiq
|
56
|
+
```
|
57
|
+
|
58
|
+
You can also disable collection of worker metrics altogether:
|
59
|
+
|
60
|
+
```
|
61
|
+
heroku config:add RAILS_AUTOSCALE_WORKER_ADAPTER=""
|
62
|
+
```
|
63
|
+
|
64
|
+
It's also possible to write a custom worker adapter. See [these docs](https://railsautoscale.com/docs/custom-worker-adapter/) for details.
|
65
|
+
|
50
66
|
## Troubleshooting
|
51
67
|
|
52
68
|
Once installed, you should see something like this in your development log:
|
@@ -59,17 +75,39 @@ In production, run `heroku logs -t | grep RailsAutoscale`, and you should see so
|
|
59
75
|
|
60
76
|
If you don't see either of these, try running `bundle` again and restarting your Rails application.
|
61
77
|
|
62
|
-
You can see more detailed (debug) logging by setting
|
78
|
+
You can see more detailed (debug) logging by setting `RAILS_AUTOSCALE_DEBUG` on your Heroku app:
|
63
79
|
|
64
80
|
```
|
65
81
|
heroku config:add RAILS_AUTOSCALE_DEBUG=true
|
66
82
|
```
|
67
83
|
|
68
|
-
|
69
|
-
and these can get very noisy with this gem.
|
84
|
+
See more in the [logging](#logging) section below.
|
70
85
|
|
71
86
|
Reach out to help@railsautoscale.com if you run into any other problems.
|
72
87
|
|
88
|
+
## Logging
|
89
|
+
|
90
|
+
The Rails logger is used by default.
|
91
|
+
If you wish to use a different logger you can set it on the configuration object:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
# config/initializers/rails_autoscale_agent.rb
|
95
|
+
RailsAutoscaleAgent::Config.instance.logger = MyLogger.new
|
96
|
+
```
|
97
|
+
|
98
|
+
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:
|
99
|
+
|
100
|
+
```
|
101
|
+
heroku config:add RAILS_AUTOSCALE_DEBUG=true
|
102
|
+
```
|
103
|
+
|
104
|
+
If you find the gem too chatty even without this, you can quiet it down further:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
# config/initializers/rails_autoscale_agent.rb
|
108
|
+
RailsAutoscaleAgent::Config.instance.quiet = true
|
109
|
+
```
|
110
|
+
|
73
111
|
## Development
|
74
112
|
|
75
113
|
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.
|
@@ -4,36 +4,34 @@ require 'singleton'
|
|
4
4
|
|
5
5
|
module RailsAutoscaleAgent
|
6
6
|
class Config
|
7
|
+
DEFAULT_WORKER_ADAPTERS = 'sidekiq,delayed_job,que,resque'
|
8
|
+
|
7
9
|
include Singleton
|
8
10
|
|
9
11
|
attr_accessor :report_interval, :logger, :api_base_url, :max_request_size,
|
10
|
-
:dyno, :
|
12
|
+
:dyno, :addon_name, :worker_adapters, :dev_mode, :debug, :quiet,
|
13
|
+
:track_long_running_jobs,
|
14
|
+
|
15
|
+
# legacy configs, no longer used
|
16
|
+
:sidekiq_latency_for_active_jobs, :latency_for_active_jobs
|
11
17
|
|
12
18
|
def initialize
|
13
|
-
|
14
|
-
require 'rails_autoscale_agent/worker_adapters/delayed_job'
|
15
|
-
require 'rails_autoscale_agent/worker_adapters/que'
|
16
|
-
require 'rails_autoscale_agent/worker_adapters/resque'
|
17
|
-
@worker_adapters = [
|
18
|
-
WorkerAdapters::Sidekiq.instance,
|
19
|
-
WorkerAdapters::DelayedJob.instance,
|
20
|
-
WorkerAdapters::Que.instance,
|
21
|
-
WorkerAdapters::Resque.instance,
|
22
|
-
]
|
19
|
+
@worker_adapters = prepare_worker_adapters
|
23
20
|
|
24
21
|
# Allow the add-on name to be configured - needed for testing
|
25
22
|
@addon_name = ENV['RAILS_AUTOSCALE_ADDON'] || 'RAILS_AUTOSCALE'
|
26
23
|
@api_base_url = ENV["#{@addon_name}_URL"]
|
27
24
|
@dev_mode = ENV['RAILS_AUTOSCALE_DEV'] == 'true'
|
28
|
-
@
|
25
|
+
@debug = dev_mode? || ENV['RAILS_AUTOSCALE_DEBUG'] == 'true'
|
26
|
+
@track_long_running_jobs = ENV['RAILS_AUTOSCALE_LONG_JOBS'] == 'true'
|
29
27
|
@max_request_size = 100_000 # ignore request payloads over 100k since they skew the queue times
|
30
28
|
@report_interval = 10 # this default will be overwritten during Reporter#register!
|
31
29
|
@logger ||= defined?(Rails) ? Rails.logger : ::Logger.new(STDOUT)
|
32
|
-
@dyno =
|
30
|
+
@dyno = dev_mode? ? 'dev.1' : ENV['DYNO']
|
33
31
|
end
|
34
32
|
|
35
33
|
def to_s
|
36
|
-
"#{@dyno}##{
|
34
|
+
"#{@dyno}##{Process.pid}"
|
37
35
|
end
|
38
36
|
|
39
37
|
def ignore_large_requests?
|
@@ -41,5 +39,18 @@ module RailsAutoscaleAgent
|
|
41
39
|
end
|
42
40
|
|
43
41
|
alias_method :dev_mode?, :dev_mode
|
42
|
+
alias_method :debug?, :debug
|
43
|
+
alias_method :quiet?, :quiet
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def prepare_worker_adapters
|
48
|
+
adapter_names = (ENV['RAILS_AUTOSCALE_WORKER_ADAPTER'] || DEFAULT_WORKER_ADAPTERS).split(',')
|
49
|
+
adapter_names.map do |adapter_name|
|
50
|
+
require "rails_autoscale_agent/worker_adapters/#{adapter_name}"
|
51
|
+
adapter_constant_name = adapter_name.capitalize.gsub(/(?:_)(.)/i) { $1.upcase }
|
52
|
+
WorkerAdapters.const_get(adapter_constant_name).instance
|
53
|
+
end
|
54
|
+
end
|
44
55
|
end
|
45
56
|
end
|
@@ -13,26 +13,33 @@ module RailsAutoscaleAgent
|
|
13
13
|
class LoggerProxy < Struct.new(:logger)
|
14
14
|
TAG = '[RailsAutoscale]'
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
#
|
26
|
-
|
27
|
-
|
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
|
@@ -20,6 +20,7 @@ module RailsAutoscaleAgent
|
|
20
20
|
def start!(config, store)
|
21
21
|
@started = true
|
22
22
|
@worker_adapters = config.worker_adapters.select(&:enabled?)
|
23
|
+
@dyno_num = config.dyno.to_s.split('.').last.to_i
|
23
24
|
|
24
25
|
if !config.api_base_url && !config.dev_mode?
|
25
26
|
logger.info "Reporter not started: #{config.addon_name}_URL is not set"
|
@@ -34,15 +35,14 @@ module RailsAutoscaleAgent
|
|
34
35
|
multiplier = 1 - (rand / 4) # between 0.75 and 1.0
|
35
36
|
sleep config.report_interval * multiplier
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
# https://ruby-doc.org/core-2.2.0/Thread.html#class-Thread-label-Exception+handling
|
43
|
-
logger.error "Reporter error: #{ex.inspect}"
|
44
|
-
AutoscaleApi.new(config.api_base_url).report_exception!(ex)
|
38
|
+
# It's redundant to report worker metrics from every web dyno, so only report from web.1
|
39
|
+
if @dyno_num == 1
|
40
|
+
@worker_adapters.map do |adapter|
|
41
|
+
report_exceptions(config) { adapter.collect!(store) }
|
42
|
+
end
|
45
43
|
end
|
44
|
+
|
45
|
+
report_exceptions(config) { report!(config, store) }
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -51,6 +51,8 @@ module RailsAutoscaleAgent
|
|
51
51
|
@started
|
52
52
|
end
|
53
53
|
|
54
|
+
private
|
55
|
+
|
54
56
|
def report!(config, store)
|
55
57
|
report = store.pop_report
|
56
58
|
|
@@ -86,5 +88,20 @@ module RailsAutoscaleAgent
|
|
86
88
|
logger.error "Reporter failed to register: #{result.failure_message}"
|
87
89
|
end
|
88
90
|
end
|
91
|
+
|
92
|
+
def report_exceptions(config)
|
93
|
+
begin
|
94
|
+
yield
|
95
|
+
rescue => ex
|
96
|
+
# Exceptions in threads other than the main thread will fail silently
|
97
|
+
# https://ruby-doc.org/core-2.2.0/Thread.html#class-Thread-label-Exception+handling
|
98
|
+
logger.error "Reporter error: #{ex.inspect}"
|
99
|
+
AutoscaleApi.new(config).report_exception!(ex)
|
100
|
+
end
|
101
|
+
rescue => ex
|
102
|
+
# An exception was encountered while trying to report the original exception.
|
103
|
+
# Swallow the error so the reporter continues to report.
|
104
|
+
logger.error "Exception reporting error: #{ex.inspect}"
|
105
|
+
end
|
89
106
|
end
|
90
107
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'rails_autoscale_agent/logger'
|
4
|
+
|
3
5
|
module RailsAutoscaleAgent
|
4
6
|
class Request
|
5
7
|
include Logger
|
@@ -9,32 +11,39 @@ module RailsAutoscaleAgent
|
|
9
11
|
@id = env['HTTP_X_REQUEST_ID']
|
10
12
|
@size = env['rack.input'].respond_to?(:size) ? env['rack.input'].size : 0
|
11
13
|
@request_body_wait = env['puma.request_body_wait'].to_i
|
14
|
+
@request_start_header = env['HTTP_X_REQUEST_START']
|
15
|
+
end
|
16
|
+
|
17
|
+
def ignore?
|
18
|
+
@config.ignore_large_requests? && @size > @config.max_request_size
|
19
|
+
end
|
12
20
|
|
13
|
-
|
14
|
-
|
15
|
-
|
21
|
+
def started_at
|
22
|
+
if @request_start_header
|
23
|
+
# Heroku sets the header as an integer, measured in milliseconds.
|
24
|
+
# If nginx is involved, it might be in seconds with fractional milliseconds,
|
25
|
+
# and it might be preceeded by "t=". We can all cases by removing non-digits
|
26
|
+
# and treating as milliseconds.
|
27
|
+
Time.at(@request_start_header.gsub(/\D/, '').to_i / 1000.0)
|
28
|
+
elsif @config.dev_mode?
|
16
29
|
# In dev mode, fake a queue time of 0-1000ms
|
17
30
|
Time.now - rand + @request_body_wait
|
18
31
|
end
|
19
32
|
end
|
20
33
|
|
21
|
-
def
|
22
|
-
|
23
|
-
end
|
34
|
+
def queue_time(now = Time.now)
|
35
|
+
return if started_at.nil?
|
24
36
|
|
25
|
-
|
26
|
-
if @entered_queue_at
|
27
|
-
queue_time = ((Time.now - @entered_queue_at) * 1000).to_i
|
37
|
+
queue_time = ((now - started_at) * 1000).to_i
|
28
38
|
|
29
|
-
|
30
|
-
|
31
|
-
|
39
|
+
# Subtract the time Puma spent waiting on the request body. It's irrelevant to capacity-related queue time.
|
40
|
+
# Without this, slow clients and large request payloads will skew queue time.
|
41
|
+
queue_time -= @request_body_wait
|
32
42
|
|
33
|
-
|
43
|
+
logger.debug "Request queue_time=#{queue_time}ms body_wait=#{@request_body_wait}ms request_id=#{@id} size=#{@size}"
|
34
44
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
45
|
+
# Safeguard against negative queue times (should not happen in practice)
|
46
|
+
queue_time > 0 ? queue_time : 0
|
38
47
|
end
|
39
48
|
end
|
40
49
|
end
|
@@ -16,10 +16,15 @@ module RailsAutoscaleAgent
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def push(value, time = Time.now, queue_name = nil, metric = nil)
|
19
|
+
# If it's been two minutes since clearing out the store, stop collecting measurements.
|
20
|
+
# There could be an issue with the reporter, and continuing to collect will consume linear memory.
|
21
|
+
return if @last_pop && @last_pop < Time.now - 120
|
22
|
+
|
19
23
|
@measurements << Measurement.new(time, value, queue_name, metric)
|
20
24
|
end
|
21
25
|
|
22
26
|
def pop_report
|
27
|
+
@last_pop = Time.now
|
23
28
|
report = Report.new
|
24
29
|
|
25
30
|
while measurement = @measurements.shift
|
@@ -8,38 +8,67 @@ module RailsAutoscaleAgent
|
|
8
8
|
include RailsAutoscaleAgent::Logger
|
9
9
|
include Singleton
|
10
10
|
|
11
|
-
|
12
|
-
attr_accessor :queues
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize
|
16
|
-
# 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?
|
21
|
-
end
|
11
|
+
attr_writer :queues
|
22
12
|
|
23
13
|
def enabled?
|
24
|
-
defined? ::Delayed
|
14
|
+
if defined?(::Delayed::Job) && defined?(::Delayed::Backend::ActiveRecord)
|
15
|
+
log_msg = String.new("DelayedJob enabled (#{::ActiveRecord::Base.default_timezone})")
|
16
|
+
log_msg << " with long-running job support" if track_long_running_jobs?
|
17
|
+
logger.info log_msg
|
18
|
+
true
|
19
|
+
end
|
25
20
|
end
|
26
21
|
|
27
22
|
def collect!(store)
|
28
23
|
log_msg = String.new
|
29
|
-
t = Time.now
|
24
|
+
t = Time.now.utc
|
25
|
+
sql = <<~SQL
|
26
|
+
SELECT COALESCE(queue, 'default'), min(run_at)
|
27
|
+
FROM delayed_jobs
|
28
|
+
WHERE locked_at IS NULL
|
29
|
+
AND failed_at IS NULL
|
30
|
+
GROUP BY queue
|
31
|
+
SQL
|
32
|
+
|
33
|
+
run_at_by_queue = Hash[select_rows(sql)]
|
34
|
+
|
35
|
+
# Don't collect worker metrics if there are unreasonable number of queues
|
36
|
+
if run_at_by_queue.size > 50
|
37
|
+
logger.debug "Skipping DelayedJob metrics - #{run_at_by_queue.size} queues"
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
self.queues = queues | run_at_by_queue.keys
|
30
42
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
43
|
+
if track_long_running_jobs?
|
44
|
+
sql = <<~SQL
|
45
|
+
SELECT COALESCE(queue, 'default'), count(*)
|
46
|
+
FROM delayed_jobs
|
47
|
+
WHERE locked_at IS NOT NULL
|
48
|
+
AND locked_by IS NOT NULL
|
49
|
+
AND failed_at IS NULL
|
50
|
+
GROUP BY 1
|
51
|
+
SQL
|
52
|
+
|
53
|
+
busy_count_by_queue = Hash[select_rows(sql)]
|
54
|
+
self.queues = queues | busy_count_by_queue.keys
|
55
|
+
end
|
35
56
|
|
36
57
|
queues.each do |queue|
|
37
|
-
next if queue.nil? || queue.empty?
|
38
58
|
run_at = run_at_by_queue[queue]
|
39
|
-
|
59
|
+
# DateTime.parse assumes a UTC string
|
60
|
+
run_at = DateTime.parse(run_at) if run_at.is_a?(String)
|
40
61
|
latency_ms = run_at ? ((t - run_at)*1000).ceil : 0
|
62
|
+
latency_ms = 0 if latency_ms < 0
|
63
|
+
|
41
64
|
store.push latency_ms, t, queue
|
42
|
-
log_msg << "dj.#{queue}=#{latency_ms} "
|
65
|
+
log_msg << "dj-qt.#{queue}=#{latency_ms} "
|
66
|
+
|
67
|
+
if track_long_running_jobs?
|
68
|
+
busy_count = busy_count_by_queue[queue] || 0
|
69
|
+
store.push busy_count, Time.now, queue, :busy
|
70
|
+
log_msg << "dj-busy.#{queue}=#{busy_count} "
|
71
|
+
end
|
43
72
|
end
|
44
73
|
|
45
74
|
logger.debug log_msg unless log_msg.empty?
|
@@ -47,19 +76,21 @@ module RailsAutoscaleAgent
|
|
47
76
|
|
48
77
|
private
|
49
78
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
79
|
+
def queues
|
80
|
+
# Track the known queues so we can continue reporting on queues that don't
|
81
|
+
# have enqueued jobs at the time of reporting.
|
82
|
+
# Assume a "default" queue so we always report *something*, even when nothing
|
83
|
+
# is enqueued.
|
84
|
+
@queues ||= Set.new(['default'])
|
85
|
+
end
|
53
86
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
WorkerAdapters::DelayedJob.queues.add queue
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
87
|
+
def track_long_running_jobs?
|
88
|
+
Config.instance.track_long_running_jobs
|
89
|
+
end
|
61
90
|
|
62
|
-
|
91
|
+
def select_rows(sql)
|
92
|
+
# This ensures the agent doesn't hold onto a DB connection any longer than necessary
|
93
|
+
ActiveRecord::Base.connection_pool.with_connection { |c| c.select_rows(sql) }
|
63
94
|
end
|
64
95
|
end
|
65
96
|
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,40 +8,64 @@ module RailsAutoscaleAgent
|
|
9
8
|
include RailsAutoscaleAgent::Logger
|
10
9
|
include Singleton
|
11
10
|
|
12
|
-
|
11
|
+
attr_writer :queues
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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?
|
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
|
39
|
+
|
40
|
+
run_at_by_queue = Hash[select_rows(sql)]
|
41
|
+
|
42
|
+
# Don't collect worker metrics if there are unreasonable number of queues
|
43
|
+
if run_at_by_queue.size > 50
|
44
|
+
logger.debug "Skipping Que metrics - #{run_at_by_queue.size} queues"
|
45
|
+
return
|
46
|
+
end
|
29
47
|
|
30
|
-
|
31
|
-
sql = 'SELECT queue, min(run_at) FROM que_jobs WHERE error_count = 0 GROUP BY queue'
|
32
|
-
run_at_by_queue = Hash[ActiveRecord::Base.connection.select_rows(sql)]
|
33
|
-
self.class.queues |= run_at_by_queue.keys
|
48
|
+
self.queues |= run_at_by_queue.keys
|
34
49
|
|
35
|
-
|
36
|
-
next if queue.nil? || queue.empty?
|
50
|
+
queues.each do |queue|
|
37
51
|
run_at = run_at_by_queue[queue]
|
38
|
-
run_at =
|
52
|
+
run_at = DateTime.parse(run_at) if run_at.is_a?(String)
|
39
53
|
latency_ms = run_at ? ((t - run_at)*1000).ceil : 0
|
54
|
+
latency_ms = 0 if latency_ms < 0
|
55
|
+
|
40
56
|
store.push latency_ms, t, queue
|
41
57
|
log_msg << "que.#{queue}=#{latency_ms} "
|
42
58
|
end
|
43
59
|
|
44
60
|
logger.debug log_msg unless log_msg.empty?
|
45
61
|
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def select_rows(sql)
|
66
|
+
# This ensures the agent doesn't hold onto a DB connection any longer than necessary
|
67
|
+
ActiveRecord::Base.connection_pool.with_connection { |c| c.select_rows(sql) }
|
68
|
+
end
|
46
69
|
end
|
47
70
|
end
|
48
71
|
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
|
@@ -17,8 +24,19 @@ module RailsAutoscaleAgent
|
|
17
24
|
|
18
25
|
def collect!(store)
|
19
26
|
log_msg = String.new
|
27
|
+
current_queues = ::Resque.queues
|
28
|
+
|
29
|
+
# Don't collect worker metrics if there are unreasonable number of queues
|
30
|
+
if current_queues.size > 50
|
31
|
+
logger.debug "Skipping Resque metrics - #{current_queues.size} queues"
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
# Ensure we continue to collect metrics for known queue names, even when nothing is
|
36
|
+
# enqueued at the time. Without this, it will appears that the agent is no longer reporting.
|
37
|
+
self.queues |= current_queues
|
20
38
|
|
21
|
-
|
39
|
+
queues.each do |queue|
|
22
40
|
next if queue.nil? || queue.empty?
|
23
41
|
depth = ::Resque.size(queue)
|
24
42
|
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 :queues
|
12
|
+
|
11
13
|
def enabled?
|
12
14
|
require 'sidekiq/api'
|
15
|
+
|
16
|
+
log_msg = String.new("Sidekiq enabled")
|
17
|
+
log_msg << " with long-running job support" if track_long_running_jobs?
|
18
|
+
logger.info log_msg
|
19
|
+
|
13
20
|
true
|
14
21
|
rescue LoadError
|
15
22
|
false
|
@@ -17,17 +24,57 @@ 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
|
20
30
|
|
21
|
-
|
31
|
+
# Don't collect worker metrics if there are unreasonable number of queues
|
32
|
+
if queues_by_name.size > 50
|
33
|
+
logger.debug "Skipping Sidekiq metrics - #{queues_by_name.size} queues"
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
# Ensure we continue to collect metrics for known queue names, even when nothing is
|
38
|
+
# enqueued at the time. Without this, it will appear that the agent is no longer reporting.
|
39
|
+
queues.each do |queue_name|
|
40
|
+
queues_by_name[queue_name] ||= ::Sidekiq::Queue.new(queue_name)
|
41
|
+
end
|
42
|
+
self.queues = queues_by_name.keys
|
43
|
+
|
44
|
+
if track_long_running_jobs?
|
45
|
+
busy_counts = Hash.new { |h,k| h[k] = 0}
|
46
|
+
::Sidekiq::Workers.new.each do |pid, tid, work|
|
47
|
+
busy_counts[work.dig('payload', 'queue')] += 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
queues_by_name.each do |queue_name, queue|
|
22
52
|
latency_ms = (queue.latency * 1000).ceil
|
23
53
|
depth = queue.size
|
54
|
+
|
24
55
|
store.push latency_ms, Time.now, queue.name, :qt
|
25
56
|
store.push depth, Time.now, queue.name, :qd
|
26
57
|
log_msg << "sidekiq-qt.#{queue.name}=#{latency_ms} sidekiq-qd.#{queue.name}=#{depth} "
|
58
|
+
|
59
|
+
if track_long_running_jobs?
|
60
|
+
busy_count = busy_counts[queue.name]
|
61
|
+
store.push busy_count, Time.now, queue.name, :busy
|
62
|
+
log_msg << "sidekiq-busy.#{queue.name}=#{busy_count} "
|
63
|
+
end
|
27
64
|
end
|
28
65
|
|
29
66
|
logger.debug log_msg
|
30
67
|
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def queues
|
72
|
+
@queues ||= ['default']
|
73
|
+
end
|
74
|
+
|
75
|
+
def track_long_running_jobs?
|
76
|
+
Config.instance.track_long_running_jobs
|
77
|
+
end
|
31
78
|
end
|
32
79
|
end
|
33
80
|
end
|
@@ -16,15 +16,5 @@ Gem::Specification.new do |spec|
|
|
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
18
|
|
19
|
-
spec.
|
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"
|
19
|
+
spec.required_ruby_version = '~> 2.5'
|
30
20
|
end
|
metadata
CHANGED
@@ -1,170 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_autoscale_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam McCrea
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
|
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'
|
167
|
-
description:
|
11
|
+
date: 2021-01-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
168
14
|
email:
|
169
15
|
- adam@adamlogic.com
|
170
16
|
executables: []
|
@@ -176,6 +22,7 @@ files:
|
|
176
22
|
- ".ruby-version"
|
177
23
|
- ".travis.yml"
|
178
24
|
- ".vscode/tasks.json"
|
25
|
+
- CHANGELOG.md
|
179
26
|
- Gemfile
|
180
27
|
- LICENSE.txt
|
181
28
|
- README.md
|
@@ -206,23 +53,23 @@ homepage: https://github.com/adamlogic/rails_autoscale_agent
|
|
206
53
|
licenses:
|
207
54
|
- MIT
|
208
55
|
metadata: {}
|
209
|
-
post_install_message:
|
56
|
+
post_install_message:
|
210
57
|
rdoc_options: []
|
211
58
|
require_paths:
|
212
59
|
- lib
|
213
60
|
required_ruby_version: !ruby/object:Gem::Requirement
|
214
61
|
requirements:
|
215
|
-
- - "
|
62
|
+
- - "~>"
|
216
63
|
- !ruby/object:Gem::Version
|
217
|
-
version: '
|
64
|
+
version: '2.5'
|
218
65
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
219
66
|
requirements:
|
220
|
-
- - "
|
67
|
+
- - ">="
|
221
68
|
- !ruby/object:Gem::Version
|
222
|
-
version:
|
69
|
+
version: '0'
|
223
70
|
requirements: []
|
224
|
-
rubygems_version: 3.
|
225
|
-
signing_key:
|
71
|
+
rubygems_version: 3.1.4
|
72
|
+
signing_key:
|
226
73
|
specification_version: 4
|
227
74
|
summary: This gem works with the Rails Autoscale Heroku add-on to automatically scale
|
228
75
|
your web dynos.
|