Class: MiddleManagement::Manager
- Inherits:
-
Object
- Object
- MiddleManagement::Manager
- Defined in:
- lib/middle_management/manager.rb
Class Method Summary collapse
- .calculate_needed_worker_count(num_jobs) ⇒ Object
- .current_jobs_count ⇒ Object
-
.enforce_number_of_current_jobs(_num_workers_last_set_at = nil, _last_enforcement_job_set_for = nil) ⇒ Object
ToDo: Figure out what to do about caching worker counts.
- .get_heroku_client ⇒ Object
- .num_jobs_changes_worker_count?(num_jobs) ⇒ Boolean
- .set_num_workers(num_workers) ⇒ Object
- .track_completion ⇒ Object
- .track_creation ⇒ Object
Class Method Details
.calculate_needed_worker_count(num_jobs) ⇒ Object
56 57 58 59 60 |
# File 'lib/middle_management/manager.rb', line 56 def self.calculate_needed_worker_count(num_jobs) ideal_worker_count = num_jobs / MiddleManagement::Config::JOBS_PER_WORKER + 1 ideal_worker_count -= 1 if num_jobs % MiddleManagement::Config::JOBS_PER_WORKER == 0 [MiddleManagement::Config::MIN_WORKERS, [ideal_worker_count, MiddleManagement::Config::MAX_WORKERS].min].max end |
.current_jobs_count ⇒ Object
48 49 50 51 52 53 54 |
# File 'lib/middle_management/manager.rb', line 48 def self.current_jobs_count if @@current_jobs_count.nil? || @@current_jobs_count == 0 || self.current_jobs_count_last_queried.nil? || self.current_jobs_count_last_queried < 1.minute.ago self.current_jobs_count = Delayed::Backend::ActiveRecord::Job.where("run_at <= ? AND failed_at IS NULL AND locked_by IS NULL", Delayed::Backend::ActiveRecord::Job.db_time_now).count self.current_jobs_count_last_queried = Time.now end @@current_jobs_count end |
.enforce_number_of_current_jobs(_num_workers_last_set_at = nil, _last_enforcement_job_set_for = nil) ⇒ Object
ToDo: Figure out what to do about caching worker counts
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/middle_management/manager.rb', line 8 def self.enforce_number_of_current_jobs(_num_workers_last_set_at = nil, _last_enforcement_job_set_for = nil) self.current_worker_count = self.get_heroku_client.info(MiddleManagement::Config::HEROKU_APP)[:workers].to_i # Do nothing if our worker figures are up-to-date return if !self.num_jobs_changes_worker_count?(self.current_jobs_count) # Load cached values if they're supplied. This is to prevent different instances # from re-querying the heroku API. self.num_workers_last_set_at = _num_workers_last_set_at unless _num_workers_last_set_at.nil? self.last_enforcement_job_set_for = _last_enforcement_job_set_for unless _last_enforcement_job_set_for.nil? # Set number of workers if we haven't set it recently if self.num_workers_last_set_at.nil? || self.num_workers_last_set_at < 10.seconds.ago || self.current_worker_count.nil? || self.current_worker_count == 0 self.set_num_workers(self.calculate_needed_worker_count(self.current_jobs_count)) self.num_workers_last_set_at = Time.now else # Schedule job with cached data if we don't have one scheduled if self.last_enforcement_job_set_for.nil? || Time.now > self.last_enforcement_job_set_for # Prevent multiple jobs within our window self.last_enforcement_job_set_for = Time.now + 10.seconds self.delay(:run_at => self.last_enforcement_job_set_for).enforce_number_of_current_jobs(self.num_workers_last_set_at, self.last_enforcement_job_set_for) # Make sure we have at least one worker running to cover the job. self.set_num_workers(1) if self.current_worker_count == 0 end end end |
.get_heroku_client ⇒ Object
72 73 74 |
# File 'lib/middle_management/manager.rb', line 72 def self.get_heroku_client Heroku::Client.new(MiddleManagement::Config::HEROKU_USERNAME, MiddleManagement::Config::HEROKU_PASSWORD) end |
.num_jobs_changes_worker_count?(num_jobs) ⇒ Boolean
62 63 64 65 66 67 68 69 70 |
# File 'lib/middle_management/manager.rb', line 62 def self.num_jobs_changes_worker_count?(num_jobs) return false if num_jobs.nil? return false if self.calculate_needed_worker_count(num_jobs) == self.current_worker_count return true if self.current_worker_count.nil? # Next two lines are verified in calculate_needed_worker_count(), but let's be safe since we're dealing with real money... return false if self.calculate_needed_worker_count(num_jobs) < MiddleManagement::Config::MIN_WORKERS return false if self.calculate_needed_worker_count(num_jobs) > MiddleManagement::Config::MAX_WORKERS true end |
.set_num_workers(num_workers) ⇒ Object
76 77 78 79 |
# File 'lib/middle_management/manager.rb', line 76 def self.set_num_workers(num_workers) self.current_worker_count = num_workers self.get_heroku_client.set_workers(MiddleManagement::Config::HEROKU_APP, num_workers) end |
.track_completion ⇒ Object
37 38 39 |
# File 'lib/middle_management/manager.rb', line 37 def self.track_completion self.current_jobs_count -= 1 end |
.track_creation ⇒ Object
33 34 35 |
# File 'lib/middle_management/manager.rb', line 33 def self.track_creation self.current_jobs_count += 1 end |