@@ -34,6 +34,10 @@ module Mosquito::Runners
3434 # The number of executors to start.
3535 getter executor_count : Int32
3636
37+ def executor_count = (count : Int32 )
38+ @executor_count = Math .max(count, 1 )
39+ end
40+
3741 getter idle_wait : Time ::Span
3842
3943 def initialize
@@ -165,7 +169,7 @@ module Mosquito::Runners
165169 spawn { @finished_notifier .send nil }
166170 end
167171
168- check_for_deceased_runners
172+ adjust_executor_pool
169173
170174 run_at_most every: Mosquito .configuration.heartbeat_interval, label: :heartbeat do
171175 observer.heartbeat
@@ -195,18 +199,26 @@ module Mosquito::Runners
195199 #
196200 # When a dead executor is found, any job it was working on has its
197201 # failure counter incremented and follows the standard retry logic.
198- def check_for_deceased_runners : Nil
202+ def adjust_executor_pool : Nil
203+ # Remove dead/crashed executors and recover their jobs.
199204 executors.select {|executor | executor.dead? || executor.state.crashed? }
200205 .each do |dead_executor |
201206 observer.executor_died dead_executor
202207 recover_job_from dead_executor
203208 executors.delete dead_executor
204209 end
205210
211+ # Scale up: spawn new executors to reach the target count.
206212 (executor_count - executors.size).times do
207213 executors << build_executor.tap(& .run)
208214 end
209215
216+ # Scale down: decommission excess executors and remove them from the pool.
217+ # They will finish their current job (if any) and then stop.
218+ while executors.size > executor_count
219+ executors.pop.decommission!
220+ end
221+
210222 observer.update_executor_list executors
211223
212224 if queue_list.dead?
@@ -274,10 +286,10 @@ module Mosquito::Runners
274286 # If a dead executor was working on a job, increment its failure
275287 # counter and follow the standard retry logic.
276288 private def recover_job_from (dead_executor : Executor ) : Nil
277- return unless job_run = dead_executor.job_run ?
289+ return unless work_unit = dead_executor.work_unit ?
278290
279- observer.recovered_job_from_executor job_run, dead_executor
280- job_run.retry_or_banish dead_executor .queue
291+ observer.recovered_job_from_executor work_unit. job_run, dead_executor
292+ work_unit. job_run.retry_or_banish work_unit .queue
281293 end
282294
283295 end
0 commit comments