web47core 3.4.11.0 → 3.4.11.2
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/README.md +8 -3
- data/lib/app/models/concerns/aws_configuration.rb +3 -0
- data/lib/app/services/auto_scaler.rb +14 -0
- data/lib/web47core/version.rb +1 -1
- metadata +33 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0c6cbc481a022be4632e12894dcbf3c8e91dc7b86a450e94c99627651bd4c827
|
|
4
|
+
data.tar.gz: 9cf223d9031627668cebcb06ceff3c2f50865a50504140dfc3c24f9e12208a4e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 186a56e4ee962b9b4ee7b925f684738f383fd2837ffbd2c74431c41faa35894d950dc4ee442503dadb0bd0d9fc85c1e183bb20640b3ba6655d9ea1620835eba7
|
|
7
|
+
data.tar.gz: 2597dad347f6e7083883202160e081418173b7f27ded2e5c4ce8034880bf7e446a5d9e4b599a4bf63ef1eba85df83ae55bbd2f491a45bb6f504adf911663e6f7
|
data/README.md
CHANGED
|
@@ -48,6 +48,10 @@ The `web47core` project is a gem that will be deployed via [Ruby Gems](https://r
|
|
|
48
48
|
2. Post the gem to the DevOps channel in slack, ask for it to be added to the S3 repo.
|
|
49
49
|
|
|
50
50
|
## Usage
|
|
51
|
+
### Worker autoscaling
|
|
52
|
+
|
|
53
|
+
`AutoScaler.check` follows `Web47core::Config.worker_ladder` and keeps existing workers until the non-failed job queue is empty. If jobs are queued but both the ladder and ECS desired count are zero, it requests one worker after more than `SystemConfiguration.aws_worker_max_wait_minutes` without a worker check-in (default: 45 minutes). Set the wait with `SystemConfiguration.configuration.update!(aws_worker_max_wait_minutes: 30)`; it must be a positive integer. With no check-in history, it requests one immediately. The cron primary checks once a minute; ECS startup takes additional time.
|
|
54
|
+
|
|
51
55
|
### Importing the gem
|
|
52
56
|
To use the `web47core` gem in a project, first add the gem to your Gemfile in one of two ways
|
|
53
57
|
|
|
@@ -256,13 +260,14 @@ bundle exec delayed_job stop
|
|
|
256
260
|
```
|
|
257
261
|
|
|
258
262
|
##### Delayed Job Management
|
|
259
|
-
|
|
260
|
-
exceed the max allowed time for a job to run. To configure this, update the delayed job initializer to add the `TimeKeeper` plugin.
|
|
263
|
+
Register `TimeKeeper` once in the host application’s delayed-job initializer. It records worker check-ins and job runs, which the autoscaler uses to detect idle workers.
|
|
261
264
|
|
|
262
265
|
```ruby
|
|
263
|
-
Delayed::Worker.plugins
|
|
266
|
+
Delayed::Worker.plugins |= [Delayed::Plugins::TimeKeeper]
|
|
264
267
|
```
|
|
265
268
|
|
|
269
|
+
Automatic orphaned-job restarts remain controlled by `delayed_job_restart_orphaned`, which defaults to false.
|
|
270
|
+
|
|
266
271
|
This will add a few now cron jobs as well as objects to the project, you can view these by adding the following routes near the delayed jobs area
|
|
267
272
|
|
|
268
273
|
```ruby
|
|
@@ -17,9 +17,12 @@ module AwsConfiguration
|
|
|
17
17
|
field :aws_desired_worker_count, type: Integer, default: 0
|
|
18
18
|
# ECS service desired count from the last DescribeServices. Not the running task count.
|
|
19
19
|
field :aws_current_worker_count, type: Integer, default: 0
|
|
20
|
+
# Maximum time without a worker check-in before overriding a zero-worker rung.
|
|
21
|
+
field :aws_worker_max_wait_minutes, type: Integer, default: 45
|
|
20
22
|
|
|
21
23
|
validates :aws_desired_worker_count, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
22
24
|
validates :aws_current_worker_count, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
25
|
+
validates :aws_worker_max_wait_minutes, numericality: { only_integer: true, greater_than: 0 }
|
|
23
26
|
end
|
|
24
27
|
end
|
|
25
28
|
|
|
@@ -9,6 +9,10 @@ require 'singleton'
|
|
|
9
9
|
# the worker ladder. It does not shrink the fleet while any job is still
|
|
10
10
|
# queued, including when the ladder maps that depth to zero workers. It
|
|
11
11
|
# scales to zero only when the queue is empty.
|
|
12
|
+
# If the ladder and live desired count are zero with jobs queued, check
|
|
13
|
+
# starts one worker after the configured wait without a worker check-in
|
|
14
|
+
# (or immediately when there is no worker history). SystemConfiguration's
|
|
15
|
+
# aws_worker_max_wait_minutes defaults to 45.
|
|
12
16
|
# warm_up raises the fleet to at least the requested floor. bump_worker adds
|
|
13
17
|
# one worker. Neither call consults the ladder or the queue, and neither
|
|
14
18
|
# lowers a fleet that is already larger.
|
|
@@ -102,6 +106,8 @@ class AutoScaler
|
|
|
102
106
|
return
|
|
103
107
|
end
|
|
104
108
|
|
|
109
|
+
target = 1 if job_count.positive? && target.zero? && current.zero? && worker_check_in_overdue?
|
|
110
|
+
|
|
105
111
|
# Keep the live fleet while any job remains. The ladder still chooses a
|
|
106
112
|
# larger fleet. Scale down only once the queue is empty.
|
|
107
113
|
if job_count.positive? && target < current
|
|
@@ -123,6 +129,14 @@ class AutoScaler
|
|
|
123
129
|
update_service(target)
|
|
124
130
|
end
|
|
125
131
|
|
|
132
|
+
def worker_check_in_overdue?
|
|
133
|
+
cutoff = configuration.aws_worker_max_wait_minutes.minutes.ago
|
|
134
|
+
!Delayed::Jobs::Worker.where(:last_check_in_at.gte => cutoff).exists?
|
|
135
|
+
rescue StandardError => error
|
|
136
|
+
App47Logger.log_error 'Unable to determine worker max wait minutes for worker', error
|
|
137
|
+
false
|
|
138
|
+
end
|
|
139
|
+
|
|
126
140
|
def desired_for(job_count)
|
|
127
141
|
worker_ladder.each do |range, workers|
|
|
128
142
|
return workers if range.cover?(job_count)
|
data/lib/web47core/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: web47core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.4.11.
|
|
4
|
+
version: 3.4.11.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Schroeder
|
|
@@ -13,30 +13,42 @@ dependencies:
|
|
|
13
13
|
name: activemodel
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: '7.2'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '8.2'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">="
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
28
|
version: '7.2'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '8.2'
|
|
26
32
|
- !ruby/object:Gem::Dependency
|
|
27
33
|
name: activesupport
|
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
|
29
35
|
requirements:
|
|
30
|
-
- - "
|
|
36
|
+
- - ">="
|
|
31
37
|
- !ruby/object:Gem::Version
|
|
32
38
|
version: '7.2'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '8.2'
|
|
33
42
|
type: :runtime
|
|
34
43
|
prerelease: false
|
|
35
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
45
|
requirements:
|
|
37
|
-
- - "
|
|
46
|
+
- - ">="
|
|
38
47
|
- !ruby/object:Gem::Version
|
|
39
48
|
version: '7.2'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '8.2'
|
|
40
52
|
- !ruby/object:Gem::Dependency
|
|
41
53
|
name: cancancan
|
|
42
54
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -403,30 +415,42 @@ dependencies:
|
|
|
403
415
|
name: rails
|
|
404
416
|
requirement: !ruby/object:Gem::Requirement
|
|
405
417
|
requirements:
|
|
406
|
-
- - "
|
|
418
|
+
- - ">="
|
|
407
419
|
- !ruby/object:Gem::Version
|
|
408
420
|
version: '7.2'
|
|
421
|
+
- - "<"
|
|
422
|
+
- !ruby/object:Gem::Version
|
|
423
|
+
version: '8.2'
|
|
409
424
|
type: :development
|
|
410
425
|
prerelease: false
|
|
411
426
|
version_requirements: !ruby/object:Gem::Requirement
|
|
412
427
|
requirements:
|
|
413
|
-
- - "
|
|
428
|
+
- - ">="
|
|
414
429
|
- !ruby/object:Gem::Version
|
|
415
430
|
version: '7.2'
|
|
431
|
+
- - "<"
|
|
432
|
+
- !ruby/object:Gem::Version
|
|
433
|
+
version: '8.2'
|
|
416
434
|
- !ruby/object:Gem::Dependency
|
|
417
435
|
name: railties
|
|
418
436
|
requirement: !ruby/object:Gem::Requirement
|
|
419
437
|
requirements:
|
|
420
|
-
- - "
|
|
438
|
+
- - ">="
|
|
421
439
|
- !ruby/object:Gem::Version
|
|
422
440
|
version: '7.2'
|
|
441
|
+
- - "<"
|
|
442
|
+
- !ruby/object:Gem::Version
|
|
443
|
+
version: '8.2'
|
|
423
444
|
type: :development
|
|
424
445
|
prerelease: false
|
|
425
446
|
version_requirements: !ruby/object:Gem::Requirement
|
|
426
447
|
requirements:
|
|
427
|
-
- - "
|
|
448
|
+
- - ">="
|
|
428
449
|
- !ruby/object:Gem::Version
|
|
429
450
|
version: '7.2'
|
|
451
|
+
- - "<"
|
|
452
|
+
- !ruby/object:Gem::Version
|
|
453
|
+
version: '8.2'
|
|
430
454
|
- !ruby/object:Gem::Dependency
|
|
431
455
|
name: rubocop
|
|
432
456
|
requirement: !ruby/object:Gem::Requirement
|