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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 531f7fe4298b5b354797092f48258f15e85fe83a3689bf05e185f419ee1534ed
4
- data.tar.gz: b6d05366a2827ef931b3a0e2b435042fc77c1ce7ecd38ee58e231e365f4289cd
3
+ metadata.gz: 0c6cbc481a022be4632e12894dcbf3c8e91dc7b86a450e94c99627651bd4c827
4
+ data.tar.gz: 9cf223d9031627668cebcb06ceff3c2f50865a50504140dfc3c24f9e12208a4e
5
5
  SHA512:
6
- metadata.gz: 235c95930b895385682ce1e753e8119b255571ad8350c616e9d8caaf09a354f95cf08e3b5539bf063963f7f52056577fd79fed3427d4a661191e82f59a87318b
7
- data.tar.gz: 2b48885d2cd08a6f07a666dc8cd5ae5c425516b08aeafc66810e5057112c8d870856b3b1d2e06283870c073a2238e1bcdaea9a2c10efb9f213da351ecbaf1b9b
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
- Since 2.1.0, there is now a built in Delayed Job monitor that will monitor delayed jobs and auto restart them if they
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 += [Delayed::Plugins::TimeKeeper]
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Web47core
4
- VERSION = '3.4.11.0'
4
+ VERSION = '3.4.11.2'
5
5
  end
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.0
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