From 1ee6a1bc69c135d7450d2627a0f59c1989ff6658 Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Thu, 14 Oct 2021 15:49:40 -0700 Subject: [PATCH 1/6] Remove job_runs.sh and associated models --- Procfile | 1 - app/controllers/health/health_controller.rb | 9 - app/controllers/health/jobs_controller.rb | 9 - app/models/job_run.rb | 44 -- bin/job_runs.sh | 49 +- config/application.yml.default | 1 - config/initializers/job_configurations.rb | 600 +++++------------- config/routes.rb | 2 +- knapsack_rspec_report.json | 7 - lib/identity_config.rb | 1 - lib/job_runner/callback_executor.rb | 51 -- lib/job_runner/health_checker.rb | 44 -- lib/job_runner/health_checker_critical.rb | 12 - lib/job_runner/job_configuration.rb | 53 -- lib/job_runner/job_run_needed_resolver.rb | 17 - lib/job_runner/lock_referee.rb | 57 -- lib/job_runner/runner.rb | 80 --- lib/tasks/job_runs.rake | 52 -- .../config/initializers/job_configurations.rb | 273 -------- .../health/health_controller_spec.rb | 26 - spec/factories/job_runs.rb | 5 - spec/models/job_run_spec.rb | 29 - .../job_runner/callback_executor_spec.rb | 58 -- .../health_checker_critical_spec.rb | 78 --- .../job_runner/health_checker_spec.rb | 51 -- .../job_run_needed_resolver_spec.rb | 38 -- spec/services/job_runner/lock_referee_spec.rb | 61 -- spec/services/job_runner/runner_spec.rb | 127 ---- 28 files changed, 178 insertions(+), 1657 deletions(-) delete mode 100644 app/controllers/health/jobs_controller.rb delete mode 100644 app/models/job_run.rb delete mode 100644 lib/job_runner/callback_executor.rb delete mode 100644 lib/job_runner/health_checker.rb delete mode 100644 lib/job_runner/health_checker_critical.rb delete mode 100644 lib/job_runner/job_configuration.rb delete mode 100644 lib/job_runner/job_run_needed_resolver.rb delete mode 100644 lib/job_runner/lock_referee.rb delete mode 100644 lib/job_runner/runner.rb delete mode 100644 lib/tasks/job_runs.rake delete mode 100644 spec/config/initializers/job_configurations.rb delete mode 100644 spec/factories/job_runs.rb delete mode 100644 spec/models/job_run_spec.rb delete mode 100644 spec/services/job_runner/callback_executor_spec.rb delete mode 100644 spec/services/job_runner/health_checker_critical_spec.rb delete mode 100644 spec/services/job_runner/health_checker_spec.rb delete mode 100644 spec/services/job_runner/job_run_needed_resolver_spec.rb delete mode 100644 spec/services/job_runner/lock_referee_spec.rb delete mode 100644 spec/services/job_runner/runner_spec.rb diff --git a/Procfile b/Procfile index e8c1f355d93..f5b4d1f46b9 100644 --- a/Procfile +++ b/Procfile @@ -1,5 +1,4 @@ web: bundle exec rackup config.ru --port ${PORT:-3000} --host ${HOST:-localhost} worker: bundle exec good_job start -job_runs: bundle exec rake job_runs:run mailcatcher: mailcatcher -f webpacker: ./bin/webpack-dev-server diff --git a/app/controllers/health/health_controller.rb b/app/controllers/health/health_controller.rb index fb653dbafc7..99927729aca 100644 --- a/app/controllers/health/health_controller.rb +++ b/app/controllers/health/health_controller.rb @@ -1,5 +1,3 @@ -require 'job_runner/runner' - module Health class HealthController < AbstractHealthController private @@ -9,14 +7,7 @@ def health_checker database: DatabaseHealthChecker, account_reset: AccountResetHealthChecker, } - if job_run_healthchecks_enabled? - checkers[:job_runner_critical] = JobRunner::HealthCheckerCritical - end MultiHealthChecker.new(**checkers) end - - def job_run_healthchecks_enabled? - IdentityConfig.store.job_run_healthchecks_enabled - end end end diff --git a/app/controllers/health/jobs_controller.rb b/app/controllers/health/jobs_controller.rb deleted file mode 100644 index f601060f130..00000000000 --- a/app/controllers/health/jobs_controller.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Health - class JobsController < AbstractHealthController - private - - def health_checker - JobRunner::HealthChecker - end - end -end diff --git a/app/models/job_run.rb b/app/models/job_run.rb deleted file mode 100644 index 96c95831f35..00000000000 --- a/app/models/job_run.rb +++ /dev/null @@ -1,44 +0,0 @@ -class JobRun < ApplicationRecord - validates :host, presence: true - validates :pid, presence: true - - after_initialize :set_default_values - - def self.with_lock - raise ArgumentError, 'Must pass block' unless block_given? - transaction do - connection.execute( - "LOCK #{connection.quote_table_name(table_name)} IN ACCESS EXCLUSIVE MODE", - ) - # Yield to caller block with the lock held - yield - end - end - - def self.clean_up_timeouts(job_name:, timeout_threshold:) - # Find all runs that did not finish and don't have an error recorded that - # are older than the timeout threshold. - where(job_name: job_name).where(finish_time: nil).where(error: nil). - where('created_at < ?', timeout_threshold).lock. - find_each(&:mark_as_timed_out) - end - - def mark_as_timed_out - return unless error.nil? && finish_time.nil? && result.nil? - - Rails.logger.debug("#{self.class.name}: Marking job #{id} as timed out") - NewRelic::Agent.notice_error("JobRun timed out: #{inspect}") - - self.error = 'Timeout' - save! - - self - end - - private - - def set_default_values - self.host ||= Socket.gethostname - self.pid ||= Process.pid - end -end diff --git a/bin/job_runs.sh b/bin/job_runs.sh index ee7242cf892..54533669f29 100755 --- a/bin/job_runs.sh +++ b/bin/job_runs.sh @@ -1,51 +1,4 @@ #!/bin/bash set -euo pipefail -usage() { - cat >&2 <&2 "+ $*" - "$@" -} - -if [ $# -lt 1 ] || [ $# -gt 2 ]; then - usage - exit 1 -fi - -PIDFILE= -if [ $# -ge 2 ]; then - PIDFILE="$2" -fi - -case $1 in - start) - # If PIDFILE is given, fork into background - if [ -n "$PIDFILE" ]; then - run rbenv exec bundle exec rake "job_runs:run[$PIDFILE]" & - # save last process pid to the pidfile - echo "$!" > "$PIDFILE" - else - run rbenv exec bundle exec rake job_runs:run - fi - ;; - stop) - pid="$(run cat "$PIDFILE")" - run kill -2 "$pid" - ;; - status) - pid="$(run cat "$PIDFILE")" - run ps -fp "$pid" - ;; - *) - usage - ;; -esac +sleep 100 diff --git a/config/application.yml.default b/config/application.yml.default index e365f610a2e..d7e066ed068 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -87,7 +87,6 @@ idv_max_attempts: '5' idv_min_age_years: '13' idv_send_link_attempt_window_in_minutes: '10' idv_send_link_max_attempts: '5' -job_run_healthchecks_enabled: 'true' liveness_checking_enabled: 'false' logins_per_ip_track_only_mode: 'false' # LexisNexis ##################################################### diff --git a/config/initializers/job_configurations.rb b/config/initializers/job_configurations.rb index cd608de9b38..fe06c85d493 100644 --- a/config/initializers/job_configurations.rb +++ b/config/initializers/job_configurations.rb @@ -1,6 +1,3 @@ -require 'job_runner/runner' -require 'job_runner/job_configuration' - cron_5m = '0/5 * * * *' interval_5m = 5 * 60 cron_1h = '0 * * * *' @@ -8,431 +5,186 @@ cron_24h = '0 0 * * *' inteval_24h = 24 * 60 * 60 -# Once we enable ruby workers in prod, we can remove all the JobRunner code and config -# and just set this hash directly -all_configs = { - # Daily GPO letter mailings - gpo_daily_letter: { - job_runner: { - name: 'Send GPO letter', - interval: inteval_24h, - timeout: 300, - callback: -> { GpoDailyJob.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'GpoDailyJob', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send account deletion confirmation notifications - account_reset_grant_requests_send_emails: { - job_runner: { - name: 'Account reset notice', - interval: interval_5m, - timeout: 4 * 60, - callback: -> { AccountReset::GrantRequestsAndSendEmails.new.perform(Time.zone.now) }, - health_critical: true, - failures_before_alarm: 2, - }, - good_job: { - class: 'AccountReset::GrantRequestsAndSendEmails', - cron: cron_5m, - args: -> { [Time.zone.now] }, - }, - }, - # Send OMB Fitara report to s3 - omb_fitara_report: { - job_runner: { - name: 'OMB Fitara report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::OmbFitaraReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::OmbFitaraReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Unique Monthly Auths Report to S3 - unique_monthly_auths: { - job_runner: { - name: 'Unique monthly auths report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::UniqueMonthlyAuthsReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::UniqueMonthlyAuthsReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Unique Yearly Auths Report to S3 - unique_yearly_auths: { - job_runner: { - name: 'Unique yearly auths report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::UniqueYearlyAuthsReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::UniqueYearlyAuthsReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Agency User Counts Report to S3 - agency_user_counts: { - job_runner: { - name: 'Agency user counts report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::AgencyUserCountsReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::AgencyUserCountsReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Total Monthly Auths Report to S3 - total_monthly_auths: { - job_runner: { - name: 'Total montly auths report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::TotalMonthlyAuthsReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::TotalMonthlyAuthsReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Sp User Counts Report to S3 - sp_user_counts: { - job_runner: { - name: 'SP user counts report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::SpUserCountsReport.new.perform(Time.zone.now) }, - }, - good_job: { - class: 'Reports::SpUserCountsReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Sp User Quotas Report to S3 - sp_user_quotas: { - job_runner: { - name: 'SP user quotas report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::SpUserQuotasReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::SpUserQuotasReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Doc Auth Funnel Report to S3 - doc_auth_funnel_report: { - job_runner: { - name: 'Doc Auth Funnel Report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::DocAuthFunnelReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::DocAuthFunnelReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Sp Success Rate Report to S3 - sp_success_rate: { - job_runner: { - name: 'SP success rate report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::SpSuccessRateReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::SpSuccessRateReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Proofing Costs Report to S3 - proofing_costs: { - job_runner: { - name: 'Proofing costs report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::ProofingCostsReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::ProofingCostsReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Doc auth drop off rates per sprint to S3 - doc_auth_dropoff_per_sprint: { - job_runner: { - name: 'Doc auth drop off rates per sprint report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::DocAuthDropOffRatesPerSprintReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::DocAuthDropOffRatesPerSprintReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # SP Costs Report to S3 - sp_costs: { - job_runner: { - name: 'SP cost report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::SpCostReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::SpCostReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Agency Invoice Supplement Report to S3 - sp_invoice_supplement_by_iaa: { - job_runner: { - name: 'SP Invoice supplement report by IAA', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::AgencyInvoiceIaaSupplementReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::AgencyInvoiceIaaSupplementReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Agency Invoice Supplement Report to S3 - sp_invoice_supplement_by_issuer: { - job_runner: { - name: 'SP Invoice supplement report by issuer', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::AgencyInvoiceIssuerSupplementReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::AgencyInvoiceIssuerSupplementReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Total SP Costs Report to S3 - total_sp_costs: { - job_runner: { - name: 'Total SP cost report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::TotalSpCostReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::TotalSpCostReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # SP Active Users Report to S3 - sp_active_users_report: { - job_runner: { - name: 'SP active users report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::SpActiveUsersReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::SpActiveUsersReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # SP Active Users Report to S3 - sp_active_users_period_pf_performance: { - job_runner: { - name: 'SP active users over period of peformance report', - interval: inteval_24h, - timeout: 300, - callback: -> do - Reports::SpActiveUsersOverPeriodOfPerformanceReport.new.perform(Time.zone.today) - end, - }, - good_job: { - class: 'Reports::SpActiveUsersOverPeriodOfPerformanceReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Doc auth drop off rates report - doc_auth_dropoff_rates: { - job_runner: { - name: 'Doc auth drop off rates report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::DocAuthDropOffRatesReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::DocAuthDropOffRatesReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # IAA Billing Report - iaa_billing_report: { - job_runner: { - name: 'IAA billing report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::IaaBillingReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::IaaBillingReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send deleted user accounts to S3 - deleted_user_accounts: { - job_runner: { - name: 'Deleted user accounts report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::DeletedUserAccountsReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::DeletedUserAccountsReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send GPO Report to S3 - gpo_report: { - job_runner: { - name: 'GPO report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::GpoReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::GpoReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Monthly GPO Letter Requests Report to S3 - gpo_monthly_letter_requests: { - job_runner: { - name: 'Monthly GPO letter requests report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::MonthlyGpoLetterRequestsReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Reports::MonthlyGpoLetterRequestsReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send Partner API reports to S3 - partner_api_reports: { - job_runner: { - name: 'Partner API report', - interval: inteval_24h, - timeout: 300, - callback: -> { Agreements::Reports::PartnerApiReport.new.perform(Time.zone.today) }, - }, - good_job: { - class: 'Agreements::Reports::PartnerApiReport', - cron: cron_24h, - args: -> { [Time.zone.today] }, - }, - }, - # Send daily auth report to S3 - daily_auths: { - job_runner: { - name: 'Daily Auth Report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::DailyAuthsReport.new.perform(Time.zone.yesterday) }, - }, - good_job: { - class: 'Reports::DailyAuthsReport', - cron: cron_24h, - args: -> { [Time.zone.yesterday] }, - }, - }, - # Send daily dropoffs report to S3 - daily_dropoffs: { - job_runner: { - name: 'Daily Dropoffs Report', - interval: inteval_24h, - timeout: 300, - callback: -> { Reports::DailyDropoffsReport.new.perform(Time.zone.yesterday) }, - }, - good_job: { - class: 'Reports::DailyDropoffsReport', - cron: cron_24h, - args: -> { [Time.zone.yesterday] }, - }, - }, - # Removes old rows from the Throttles table - remove_old_throttles: { - job_runner: { - name: 'Remove Old Throttles', - interval: interval_1h, - timeout: 300, - callback: -> { RemoveOldThrottlesJob.new.perform(Time.zone.now) }, - }, - good_job: { - class: 'RemoveOldThrottlesJob', - cron: cron_1h, - args: -> { [Time.zone.now] }, - }, - }, -} - -if IdentityConfig.store.ruby_workers_cron_enabled - # Queue heartbeat job to GoodJob - all_configs[:heartbeat_job] = { - good_job: { - class: 'HeartbeatJob', - cron: cron_5m, - }, - } -end - if defined?(Rails::Console) Rails.logger.info 'job_configurations: console detected, skipping schedule' -elsif IdentityConfig.store.ruby_workers_cron_enabled +else Rails.application.configure do - config.good_job.cron = all_configs.transform_values { |config| config.fetch(:good_job) } + config.good_job.cron = { + # Daily GPO letter mailings + gpo_daily_letter: { + class: 'GpoDailyJob', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send account deletion confirmation notifications + account_reset_grant_requests_send_emails: { + class: 'AccountReset::GrantRequestsAndSendEmails', + cron: cron_5m, + args: -> { [Time.zone.now] }, + }, + # Send OMB Fitara report to s3 + omb_fitara_report: { + class: 'Reports::OmbFitaraReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Unique Monthly Auths Report to S3 + unique_monthly_auths: { + class: 'Reports::UniqueMonthlyAuthsReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Unique Yearly Auths Report to S3 + unique_yearly_auths: { + class: 'Reports::UniqueYearlyAuthsReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Agency User Counts Report to S3 + agency_user_counts: { + class: 'Reports::AgencyUserCountsReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Total Monthly Auths Report to S3 + total_monthly_auths: { + class: 'Reports::TotalMonthlyAuthsReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Sp User Counts Report to S3 + sp_user_counts: { + class: 'Reports::SpUserCountsReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Sp User Quotas Report to S3 + sp_user_quotas: { + class: 'Reports::SpUserQuotasReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Doc Auth Funnel Report to S3 + doc_auth_funnel_report: { + class: 'Reports::DocAuthFunnelReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Sp Success Rate Report to S3 + sp_success_rate: { + class: 'Reports::SpSuccessRateReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Proofing Costs Report to S3 + proofing_costs: { + class: 'Reports::ProofingCostsReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Doc auth drop off rates per sprint to S3 + doc_auth_dropoff_per_sprint: { + class: 'Reports::DocAuthDropOffRatesPerSprintReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # SP Costs Report to S3 + sp_costs: { + class: 'Reports::SpCostReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Agency Invoice Supplement Report to S3 + sp_invoice_supplement_by_iaa: { + class: 'Reports::AgencyInvoiceIaaSupplementReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Agency Invoice Supplement Report to S3 + sp_invoice_supplement_by_issuer: { + class: 'Reports::AgencyInvoiceIssuerSupplementReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Total SP Costs Report to S3 + total_sp_costs: { + class: 'Reports::TotalSpCostReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # SP Active Users Report to S3 + sp_active_users_report: { + class: 'Reports::SpActiveUsersReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # SP Active Users Report to S3 + sp_active_users_period_pf_performance: { + class: 'Reports::SpActiveUsersOverPeriodOfPerformanceReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Doc auth drop off rates report + doc_auth_dropoff_rates: { + class: 'Reports::DocAuthDropOffRatesReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # IAA Billing Report + iaa_billing_report: { + class: 'Reports::IaaBillingReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send deleted user accounts to S3 + deleted_user_accounts: { + class: 'Reports::DeletedUserAccountsReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send GPO Report to S3 + gpo_report: { + class: 'Reports::GpoReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Monthly GPO Letter Requests Report to S3 + gpo_monthly_letter_requests: { + class: 'Reports::MonthlyGpoLetterRequestsReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send Partner API reports to S3 + partner_api_reports: { + class: 'Agreements::Reports::PartnerApiReport', + cron: cron_24h, + args: -> { [Time.zone.today] }, + }, + # Send daily auth report to S3 + daily_auths: { + class: 'Reports::DailyAuthsReport', + cron: cron_24h, + args: -> { [Time.zone.yesterday] }, + }, + # Send daily dropoffs report to S3 + daily_dropoffs: { + class: 'Reports::DailyDropoffsReport', + cron: cron_24h, + args: -> { [Time.zone.yesterday] }, + }, + # Removes old rows from the Throttles table + remove_old_throttles: { + class: 'RemoveOldThrottlesJob', + cron: cron_1h, + args: -> { [Time.zone.now] }, + }, + # Queue heartbeat job to GoodJob + heartbeat_job: { + class: 'HeartbeatJob', + cron: cron_5m, + } + } end Rails.logger.info 'job_configurations: jobs scheduled with good_job.cron' -else - all_configs.each do |_key, config| - JobRunner::Runner.add_config( - JobRunner::JobConfiguration.new(**config.fetch(:job_runner)), - ) - end - - Rails.logger.info 'job_configurations: jobs scheduled with JobRunner::Runner' end diff --git a/config/routes.rb b/config/routes.rb index dcb7d2a40a6..2fdb7f45870 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,7 +2,7 @@ # Non i18n routes. Alphabetically sorted. get '/api/health' => 'health/health#index' get '/api/health/database' => 'health/database#index' - get '/api/health/jobs' => 'health/jobs#index' + get '/api/health/jobs' => 'health/health#index' get '/api/health/outbound' => 'health/outbound#index' get '/api/openid_connect/certs' => 'openid_connect/certs#index' post '/api/openid_connect/token' => 'openid_connect/token#create' diff --git a/knapsack_rspec_report.json b/knapsack_rspec_report.json index 4a2db49a789..58042a609d8 100644 --- a/knapsack_rspec_report.json +++ b/knapsack_rspec_report.json @@ -356,7 +356,6 @@ "spec/models/email_address_spec.rb": 0.137845000019297, "spec/models/event_spec.rb": 0.022779999999329448, "spec/models/gpo_confirmation_code_spec.rb": 0.12638900004094467, - "spec/models/job_run_spec.rb": 0.024277999997138977, "spec/models/monthly_auth_count_spec.rb": 0.024175000027753413, "spec/models/null_identity_spec.rb": 0.0020650000078603625, "spec/models/otp_requests_tracker_spec.rb": 0.03390199999557808, @@ -563,12 +562,6 @@ "spec/services/idv/session_spec.rb": 0.19095199997536838, "spec/services/idv/steps/verify_step_spec.rb": 0.09351799997966737, "spec/services/image_upload_presigned_url_generator_spec.rb": 0.008743999991565943, - "spec/services/job_runner/callback_executor_spec.rb": 0.02491300000110641, - "spec/services/job_runner/health_checker_critical_spec.rb": 0.04633900005137548, - "spec/services/job_runner/health_checker_spec.rb": 0.017072000016923994, - "spec/services/job_runner/job_run_needed_resolver_spec.rb": 0.025574999977834523, - "spec/services/job_runner/lock_referee_spec.rb": 0.033220000041183084, - "spec/services/job_runner/runner_spec.rb": 0.14460599998710677, "spec/services/key_rotator/attribute_encryption_spec.rb": 0.035191000031773, "spec/services/key_rotator/hmac_fingerprinter_spec.rb": 0.16919799998868257, "spec/services/maintenance_window_spec.rb": 0.029925000038929284, diff --git a/lib/identity_config.rb b/lib/identity_config.rb index a910632b91f..98757cdf49b 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -152,7 +152,6 @@ def self.build_store(config_map) config.add(:idv_min_age_years, type: :integer) config.add(:idv_send_link_attempt_window_in_minutes, type: :integer) config.add(:idv_send_link_max_attempts, type: :integer) - config.add(:job_run_healthchecks_enabled, type: :boolean) config.add(:lexisnexis_base_url, type: :string) config.add(:lexisnexis_request_mode, type: :string) config.add(:lexisnexis_account_id, type: :string) diff --git a/lib/job_runner/callback_executor.rb b/lib/job_runner/callback_executor.rb deleted file mode 100644 index fbee538e16c..00000000000 --- a/lib/job_runner/callback_executor.rb +++ /dev/null @@ -1,51 +0,0 @@ -module JobRunner - class CallbackExecutor - attr_reader :job_run, :job_configuration - - def initialize(job_run:, job_configuration:) - @job_run = job_run - @job_configuration = job_configuration - end - - def execute_job - ::NewRelic::Agent::Tracer.in_transaction( - partial_name: "JobRun/execute/#{job_run.job_name}", - category: :task, - ) do - log_execution_started_message - execute_job_and_save_result - log_execution_completed_message - end - end - - private - - def execute_job_and_save_result - job_run.result = job_configuration.callback.call - job_run - rescue StandardError => error - handle_job_run_error(job_run: job_run, error: error) - job_run - ensure - job_run.finish_time = Time.zone.now - job_run.save! - end - - def handle_job_run_error(job_run:, error:) - job_run.error = error.inspect - NewRelic::Agent.notice_error(error) - end - - def log_execution_started_message - Rails.logger.debug("#{job_configuration}: executing callback") - end - - def log_execution_completed_message - if job_run.error? - Rails.logger.warn("#{job_configuration}: Job failed: #{job_run.error}") - else - Rails.logger.info("#{job_configuration}: Job finished successfully") - end - end - end -end diff --git a/lib/job_runner/health_checker.rb b/lib/job_runner/health_checker.rb deleted file mode 100644 index e3dc958332d..00000000000 --- a/lib/job_runner/health_checker.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -module JobRunner - class HealthChecker - class << self - def check - jobs = Runner.configurations.select do |job_configuration| - job_selected_for_checking?(job_configuration) - end - - result = jobs.map do |job_configuration| - [job_configuration.name, successful_recent_job_run?(job_configuration)] - end.to_h - healthy = !result.value?(false) - HealthCheckSummary.new(healthy: healthy, result: result) - end - - private - - # Override this method to filter out some jobs as not checked. - # By default, return true always and check all jobs - # - # @return Boolean - # - def job_selected_for_checking?(_job_configuration) - true - end - - # Return whether there has been a succesful run of the given job - # configuration in the last N runs, where N is the job configuration's - # defined `failures_before_alarm`. - # - # @param [JobConfiguration] job_configuration - # @return [Boolean] - # - def successful_recent_job_run?(job_configuration) - interval_window = job_configuration.interval * job_configuration.failures_before_alarm - JobRun.where(job_name: job_configuration.name, error: nil). - where('created_at > ?', interval_window.seconds.ago). - any? - end - end - end -end diff --git a/lib/job_runner/health_checker_critical.rb b/lib/job_runner/health_checker_critical.rb deleted file mode 100644 index 625f7954f19..00000000000 --- a/lib/job_runner/health_checker_critical.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module JobRunner - # A subclass of the standard HealthChecker that only looks at job - # configurations that are marked with `health_critical: true`. - class HealthCheckerCritical < HealthChecker - # Select only jobs with #health_critical? => true. - def self.job_selected_for_checking?(job_configuration) - job_configuration.health_critical? - end - end -end diff --git a/lib/job_runner/job_configuration.rb b/lib/job_runner/job_configuration.rb deleted file mode 100644 index a5ea5d2e4eb..00000000000 --- a/lib/job_runner/job_configuration.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'job_runner/lock_referee' - -module JobRunner - class JobConfiguration - attr_reader :name - attr_reader :interval - attr_reader :timeout - attr_reader :callback - attr_reader :failures_before_alarm - - # @param [String] name The name of the job - # @param [Integer] interval How often a job should run (seconds) - # @param [Integer, nil] timeout How long to wait for a job to run before - # assuming it has timed out (seconds) - # @param [Callable] callback The actual job code - # @param [Boolean] health_critical Whether this job is critical enough to - # be incorporated in the main app health check. - # @param [Integer] failures_before_alarm The number of acceptable failed - # runs before the health check should alarm. - # - def initialize(name:, interval:, callback:, timeout: nil, health_critical: false, - failures_before_alarm: 1) - @name = name - @interval = interval - @timeout = timeout || interval - @callback = callback - @health_critical = health_critical - @failures_before_alarm = failures_before_alarm - end - - def to_s - "JobConfiguration #{name.inspect}" - end - - def health_critical? - if @health_critical - true - else - false - end - end - - def run_if_needed - Rails.logger.debug("#{self}: Running job") - LockReferee.new(self).acquire_lock_and_run_callback_if_needed - end - - def clean_up_timeouts - Rails.logger.debug("#{self}: Looking for job timeouts to clean up") - JobRun.clean_up_timeouts(job_name: name, timeout_threshold: Time.zone.now - timeout) - end - end -end diff --git a/lib/job_runner/job_run_needed_resolver.rb b/lib/job_runner/job_run_needed_resolver.rb deleted file mode 100644 index ff11f25ca98..00000000000 --- a/lib/job_runner/job_run_needed_resolver.rb +++ /dev/null @@ -1,17 +0,0 @@ -module JobRunner - class JobRunNeededResolver - attr_reader :job_configuration, :current_job - - def initialize(job_configuration) - @job_configuration = job_configuration - end - - def new_job_needs_to_run? - interval_threshold = Time.zone.now - job_configuration.interval - @current_job = JobRun.where(job_name: job_configuration.name). - where('created_at > ?', interval_threshold). - order(created_at: :desc).first - current_job.nil? - end - end -end diff --git a/lib/job_runner/lock_referee.rb b/lib/job_runner/lock_referee.rb deleted file mode 100644 index 96ef3514ead..00000000000 --- a/lib/job_runner/lock_referee.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'job_runner/callback_executor' -require 'job_runner/job_run_needed_resolver' - -module JobRunner - class LockReferee - attr_reader :job_configuration - - def initialize(job_configuration) - @job_configuration = job_configuration - end - - def acquire_lock_and_run_callback_if_needed - log_check_if_run_needed_message - job_run = nil - return unless run_needed? - JobRun.with_lock do - # Check again that we need to run with the lock acquired - return log_race_lost_message unless run_needed? - - log_executing_job_message - job_run = JobRun.create!(job_name: job_configuration.name) - end - CallbackExecutor.new(job_configuration: job_configuration, job_run: job_run).execute_job - log_done_message - end - - private - - def run_needed? - resolver = JobRunNeededResolver.new(job_configuration) - return true if resolver.new_job_needs_to_run? - log_run_not_needed_message(resolver.current_job.created_at) - false - end - - def log_check_if_run_needed_message - Rails.logger.info("#{job_configuration}: Checking if run is needed") - end - - def log_race_lost_message - race_lost_message = "#{job_configuration}: Due for run, but someone else won the race" - Rails.logger.info(race_lost_message) - end - - def log_executing_job_message - Rails.logger.info("#{job_configuration}: Executing job") - end - - def log_done_message - Rails.logger.debug("#{job_configuration}: Done") - end - - def log_run_not_needed_message(last_run) - Rails.logger.info("#{job_configuration}: Not yet due to run. Last run: #{last_run}") - end - end -end diff --git a/lib/job_runner/runner.rb b/lib/job_runner/runner.rb deleted file mode 100644 index 2589e37537a..00000000000 --- a/lib/job_runner/runner.rb +++ /dev/null @@ -1,80 +0,0 @@ -require 'job_runner/health_checker' -require 'job_runner/health_checker_critical' - -module JobRunner - # The Runner class manages the list of known configurations and is - # responsible for running all of them in turn when {#run} is called. - class Runner - # The list of known job configurations. Calling {#run} will execute these - # jobs according to their schedules. Add new configurations to this list by - # calling {.add_config} aka {.add_configuration}. - # - # @return [Array] - # - def self.configurations - @configurations ||= [] - # dup and freeze so that callers have to use add_config to add jobs - @configurations.dup.freeze - end - - # Empty the job configurations list. - def self.clear_configurations - @configurations = [] - end - - # Load the disabled job list from config. Provides a way to disable jobs - # without changing code. - def self.disabled_jobs - @disabled_jobs ||= IdentityConfig.store.recurring_jobs_disabled_names - end - - # Add a new job configuration to the list of jobs to run. This is the - # primary entrypoint for users to add new jobs. - # - # @param [JobRunner::JobConfiguration] job_config - # - # @see .configurations - # - def self.add_configuration(job_config) - unless job_config.is_a?(JobRunner::JobConfiguration) - raise ArgumentError, 'job_config must be a JobRunner::JobConfiguration' - end - - if disabled_jobs.include?(job_config.name) - Rails.logger.warn("JobRunner: skipping disabled job: #{job_config.name.inspect}") - return false - end - - @configurations ||= [] - @configurations << job_config - end - - class << self - alias add_config add_configuration - end - - def run - log_beginning_to_run_message - self.class.configurations.each do |configuration| - log_running_configuration_message(configuration) - configuration.clean_up_timeouts - configuration.run_if_needed - end - log_finished_run_message - end - - private - - def log_beginning_to_run_message - Rails.logger.info("#{self.class.name}: Beginning job run") - end - - def log_running_configuration_message(job_configuration) - Rails.logger.debug("Processing #{job_configuration.inspect}") - end - - def log_finished_run_message - Rails.logger.info("#{self.class.name}: Finished job run") - end - end -end diff --git a/lib/tasks/job_runs.rake b/lib/tasks/job_runs.rake deleted file mode 100644 index 7982df30545..00000000000 --- a/lib/tasks/job_runs.rake +++ /dev/null @@ -1,52 +0,0 @@ -namespace :job_runs do - task :run, [:pidfile] => :environment do |_t, args| - warn 'Calling job runner. See rails log for output.' - - # This task is used in development by foreman, if it exits early, - # it terminates the other processes, so we just have it loop forever until - # we fully transition to good_job - if IdentityConfig.store.ruby_workers_cron_enabled - loop do - sleep 60 - end - end - - require 'job_runner/runner' - require 'job_runner/job_configuration' - - @keep_jobs_loop = true - @jobs_pid_file = nil - - # use provided pidfile path, if any - @jobs_pid_file = args.pidfile - - warn "rake job_runs:run starting with PID #{Process.pid}" - - if @jobs_pid_file - warn 'Writing to pidfile at ' + @jobs_pid_file.inspect - File.write(@jobs_pid_file, Process.pid.to_s) - end - - def shut_down - File.unlink(@jobs_pid_file) if @jobs_pid_file - @keep_jobs_loop = false - Rails.logger.warn('Shutting down gracefully...') - warn "\nShutting down gracefully..." - end - - # Trap ^C - Signal.trap('INT') do - shut_down - end - - while @keep_jobs_loop - JobRunner::Runner.new.run - - # sleep 60, but bail out early if we are shutting down - 60.times do - sleep 1 - break unless @keep_jobs_loop - end - end - end -end diff --git a/spec/config/initializers/job_configurations.rb b/spec/config/initializers/job_configurations.rb deleted file mode 100644 index 12c1a225779..00000000000 --- a/spec/config/initializers/job_configurations.rb +++ /dev/null @@ -1,273 +0,0 @@ -require 'rails_helper' - -describe JobRunner::Runner do - describe '.configurations' do - it 'has the GPO letter job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'Send GPO letter' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - stub = instance_double(GpoConfirmationUploader) - expect(GpoConfirmationUploader).to receive(:new).and_return(stub) - expect(stub).to receive(:run).and_return('the GPO test worked') - - result = CalendarService.weekend_or_holiday?(Time.zone.today) ? nil : 'the GPO test worked' - expect(job.callback.call).to eq result - end - - it 'runs the account reset job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'Account reset notice' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 300 - - service = instance_double(AccountReset::GrantRequestsAndSendEmails) - expect(AccountReset::GrantRequestsAndSendEmails).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the reset test worked') - - expect(job.callback.call).to eq 'the reset test worked' - end - - it 'runs the OMB Fitara report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'OMB Fitara report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::OmbFitaraReport) - expect(Reports::OmbFitaraReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the monthly unique auths report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'Unique montly auths report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::UniqueMonthlyAuthsReport) - expect(Reports::UniqueMonthlyAuthsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the yearly unique auths report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'Unique yearly auths report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::UniqueYearlyAuthsReport) - expect(Reports::UniqueYearlyAuthsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the agency user counts report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'Agency user counts report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::AgencyUserCountsReport) - expect(Reports::AgencyUserCountsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the total monthly auths report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'Total montly auths report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::TotalMonthlyAuthsReport) - expect(Reports::TotalMonthlyAuthsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the sp user counts report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'SP user counts report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::SpUserCountsReport) - expect(Reports::SpUserCountsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the sp user quotas report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'SP user quotas report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::SpUserQuotasReport) - expect(Reports::SpUserQuotasReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the sp success rate report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'SP success rate report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::SpSuccessRateReport) - expect(Reports::SpSuccessRateReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the proofing costs report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'Proofing costs report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::ProofingCostsReport) - expect(Reports::ProofingCostsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the doc auth drop offs per sprint report job' do - job = JobRunner::Runner.configurations.find do |c| - c.name == 'Doc auth drop off rates per sprint report' - end - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::DocAuthDropOffRatesPerSprintReport) - expect(Reports::DocAuthDropOffRatesPerSprintReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the SP cost report job' do - job = JobRunner::Runner.configurations.find do |c| - c.name == 'SP cost report' - end - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::SpCostReport) - expect(Reports::SpCostReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the total SP cost report job' do - job = JobRunner::Runner.configurations.find do |c| - c.name == 'Total SP cost report' - end - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::TotalSpCostReport) - expect(Reports::TotalSpCostReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the SP active users report job' do - job = JobRunner::Runner.configurations.find do |c| - c.name == 'SP active users report' - end - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::SpActiveUsersReport) - expect(Reports::SpActiveUsersReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the SP active users over period of performance report job' do - job = JobRunner::Runner.configurations.find do |c| - c.name == 'SP active users over period of performance report' - end - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::SpActiveUsersOverPeriodOfPerformanceReport) - expect(Reports::SpActiveUsersOverPeriodOfPerformanceReport).to receive(:new). - and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the doc auth drop offs report job' do - job = JobRunner::Runner.configurations.find do |c| - c.name == 'Doc auth drop off rates report' - end - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::DocAuthDropOffRatesReport) - expect(Reports::DocAuthDropOffRatesReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the iaa billing report job' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'IAA Billing report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::IaaBillingReport) - expect(Reports::IaaBillingReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'emails the deleted UUIDs report' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'Deleted UUIDs report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::DeletedUserAccountsReport) - expect(Reports::DeletedUserAccountsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the GPO report' do - job = JobRunner::Runner.configurations.find { |c| c.name == 'USPS report' } - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::UspsReport) - expect(Reports::UspsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - - it 'runs the Monthly GPO letter requests report' do - job = JobRunner::Runner.configurations.find do |c| - c.name == 'Monthly GPO letter requests report' - end - expect(job).to be_instance_of(JobRunner::JobConfiguration) - expect(job.interval).to eq 24 * 60 * 60 - - service = instance_double(Reports::MonthlyGpoLetterRequestsReport) - expect(Reports::MonthlyGpoLetterRequestsReport).to receive(:new).and_return(service) - expect(service).to receive(:call).and_return('the report test worked') - - expect(job.callback.call).to eq 'the report test worked' - end - end -end diff --git a/spec/controllers/health/health_controller_spec.rb b/spec/controllers/health/health_controller_spec.rb index ce0a9cc1317..d78b40aa23d 100644 --- a/spec/controllers/health/health_controller_spec.rb +++ b/spec/controllers/health/health_controller_spec.rb @@ -1,10 +1,6 @@ require 'rails_helper' RSpec.describe Health::HealthController do - before do - allow(IdentityConfig.store).to receive(:job_run_healthchecks_enabled).and_return(true) - end - describe '#index' do context 'when all checked resources are healthy' do it 'returns a successful JSON response' do @@ -21,7 +17,6 @@ expect(json[:healthy]).to eq(true) expect(json[:statuses][:database][:healthy]).to eq(true) expect(json[:statuses][:account_reset][:healthy]).to eq(true) - expect(json[:statuses][:job_runner_critical][:healthy]).to eq(true) end end @@ -41,7 +36,6 @@ expect(json[:statuses][:database][:result]). to include('canceling statement due to statement timeout') expect(json[:statuses][:account_reset][:healthy]).to eq(true) - expect(json[:statuses][:job_runner_critical][:healthy]).to eq(true) expect(response.status).to eq(500) end end @@ -62,28 +56,8 @@ expect(json[:statuses][:database][:result]). to include('canceling statement due to statement timeout') expect(json[:statuses][:account_reset][:healthy]).to eq(false) - expect(json[:statuses][:job_runner_critical][:healthy]).to eq(false) expect(response.status).to eq(500) end end - - context 'job run healthchecks are disabled' do - it 'does not include job run healthchecks' do - allow(IdentityConfig.store).to receive(:job_run_healthchecks_enabled).and_return(false) - - allow(DatabaseHealthChecker).to receive(:simple_query).and_return('foo') - allow(AccountResetHealthChecker).to receive(:check). - and_return(HealthCheckSummary.new(healthy: true, result: 'foo')) - - get :index - json = JSON.parse(response.body, symbolize_names: true) - - expect(response.status).to eq(200) - expect(json[:healthy]).to eq(true) - expect(json[:statuses][:database][:healthy]).to eq(true) - expect(json[:statuses][:account_reset][:healthy]).to eq(true) - expect(json[:statuses][:job_runner_critical]).to eq(nil) - end - end end end diff --git a/spec/factories/job_runs.rb b/spec/factories/job_runs.rb deleted file mode 100644 index a53797bb080..00000000000 --- a/spec/factories/job_runs.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.define do - factory :job_run do - job_name { 'Send GPO letter' } - end -end diff --git a/spec/models/job_run_spec.rb b/spec/models/job_run_spec.rb deleted file mode 100644 index 02b5e0d21c7..00000000000 --- a/spec/models/job_run_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'rails_helper' - -describe JobRun do - describe '.clean_up_timeouts' do - it 'marks old unfinished jobs as timed out' do - finished_job = create(:job_run, finish_time: 1.minute.ago, result: 'Ok') - errored_job = create(:job_run, finish_time: 1.minute.ago, error: 'Sad') - running_job = create(:job_run, created_at: 1.minute.ago) - timedout_job = create(:job_run, created_at: 3.minutes.ago) - timedout_job_with_different_nane = create( - :job_run, - job_name: 'Diffy', - created_at: 3.minutes.ago, - ) - - expect(NewRelic::Agent).to receive(:notice_error).with(/JobRun timed out/) - - JobRun.clean_up_timeouts(job_name: timedout_job.job_name, timeout_threshold: 2.minutes.ago) - - expect(timedout_job.reload.error).to eq('Timeout') - expect(finished_job).to eq(JobRun.find(finished_job.id)) - expect(errored_job).to eq(JobRun.find(errored_job.id)) - expect(running_job).to eq(JobRun.find(running_job.id)) - expect(timedout_job_with_different_nane).to eq( - JobRun.find(timedout_job_with_different_nane.id), - ) - end - end -end diff --git a/spec/services/job_runner/callback_executor_spec.rb b/spec/services/job_runner/callback_executor_spec.rb deleted file mode 100644 index c7c4d25dee1..00000000000 --- a/spec/services/job_runner/callback_executor_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'rails_helper' - -describe JobRunner::CallbackExecutor do - describe '#execute_job' do - let(:job_run) { create(:job_run) } - - subject { described_class.new(job_run: job_run, job_configuration: job_configuration) } - - context 'when the job succeeds' do - let(:job_configuration) do - JobRunner::JobConfiguration.new( - name: 'Send GPO letter', - interval: 5 * 60, - timeout: 60, - callback: -> { 'Hello!' }, - ) - end - - it 'saves the result' do - subject.execute_job - - expect(job_run.reload.result).to eq('Hello!') - expect(job_run.error).to eq(nil) - expect(job_run.finish_time).to be_within(1.second).of(Time.zone.now) - end - end - - context 'when the job fails' do - let(:error) do - runtime_error = RuntimeError.new('test') - allow(runtime_error).to receive(:inspect).and_return('test error inspected') - runtime_error - end - let(:job_configuration) do - JobRunner::JobConfiguration.new( - name: 'Send GPO letter', - interval: 5 * 60, - timeout: 60, - callback: -> { raise(error) }, - ) - end - - it 'saves the error' do - subject.execute_job - - expect(job_run.reload.result).to eq(nil) - expect(job_run.error).to eq('test error inspected') - expect(job_run.finish_time).to be_within(1.second).of(Time.zone.now) - end - - it 'reports the error to NewRelic' do - expect(NewRelic::Agent).to receive(:notice_error).with(error) - - subject.execute_job - end - end - end -end diff --git a/spec/services/job_runner/health_checker_critical_spec.rb b/spec/services/job_runner/health_checker_critical_spec.rb deleted file mode 100644 index 2a8bf9c36ef..00000000000 --- a/spec/services/job_runner/health_checker_critical_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'rails_helper' - -describe JobRunner::HealthCheckerCritical do - before do - configurations = [] - configurations << JobRunner::JobConfiguration.new( - name: 'test job 1', - interval: 5 * 60, # 5 minutes - timeout: 60, - callback: -> { 'test job 1 result' }, - health_critical: true, - ) - configurations << JobRunner::JobConfiguration.new( - name: 'normal job', - interval: 60 * 60, - timeout: 60 * 30, - callback: -> { 'normal job result' }, - ) - configurations << JobRunner::JobConfiguration.new( - name: 'test job 3', - interval: 60 * 60, # hourly - timeout: 60, - callback: -> { 'test job 3 result' }, - health_critical: true, - failures_before_alarm: 2, - ) - allow(JobRunner::Runner).to receive(:configurations).and_return(configurations) - end - - context 'when all of the jobs have run within allowed intervals' do - it 'returns a healthy summary' do - create(:job_run, job_name: 'test job 1', created_at: 4.minutes.ago) - create(:job_run, job_name: 'normal job', created_at: 20.minutes.ago) - create(:job_run, job_name: 'test job 3', created_at: 119.minutes.ago) - - expected_summary = { healthy: true, result: { 'test job 1' => true, 'test job 3' => true } } - - result = described_class.check - - expect(result.healthy?).to eq(true) - expect(result.to_h).to eq(expected_summary) - expect(result.as_json).to eq(expected_summary.as_json) - end - end - - context 'when critical jobs are just over allowed threshold' do - it 'returns an unhealthy summary' do - create(:job_run, job_name: 'test job 1', created_at: 6.minutes.ago) - create(:job_run, job_name: 'normal job', created_at: 20.minutes.ago) - create(:job_run, job_name: 'test job 3', created_at: 121.minutes.ago) - - expected_summary = { healthy: false, - result: { 'test job 1' => false, 'test job 3' => false } } - - result = described_class.check - - expect(result.healthy?).to eq(false) - expect(result.to_h).to eq(expected_summary) - expect(result.as_json).to eq(expected_summary.as_json) - end - end - - context 'when there is a non-critical job that has not run' do - it 'returns a healthy summary' do - create(:job_run, job_name: 'test job 1', created_at: 4.minutes.ago) - create(:job_run, job_name: 'normal job', created_at: 300.minutes.ago) - create(:job_run, job_name: 'test job 3', created_at: 90.minutes.ago) - - expected_summary = { healthy: true, result: { 'test job 1' => true, 'test job 3' => true } } - - result = described_class.check - - expect(result.healthy?).to eq(true) - expect(result.to_h).to eq(expected_summary) - expect(result.as_json).to eq(expected_summary.as_json) - end - end -end diff --git a/spec/services/job_runner/health_checker_spec.rb b/spec/services/job_runner/health_checker_spec.rb deleted file mode 100644 index 5ddb95a2fed..00000000000 --- a/spec/services/job_runner/health_checker_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'rails_helper' - -describe JobRunner::HealthChecker do - before do - configurations = [] - configurations << JobRunner::JobConfiguration.new( - name: 'test job 1', - interval: 5 * 60, # 5 minutes - timeout: 60, - callback: -> { 'test job 1 result' }, - failures_before_alarm: 3, - ) - configurations << JobRunner::JobConfiguration.new( - name: 'test job 2', - interval: 60 * 60, # hourly - timeout: 60 * 30, - callback: -> { 'test job 2 result' }, - ) - allow(JobRunner::Runner).to receive(:configurations).and_return(configurations) - end - - context 'when all of the jobs have run as scheduled' do - it 'returns a healthy summary' do - create(:job_run, job_name: 'test job 1', created_at: 14.minutes.ago) - create(:job_run, job_name: 'test job 2', created_at: 20.minutes.ago) - - expected_summary = { healthy: true, result: { 'test job 1' => true, 'test job 2' => true } } - - result = described_class.check - - expect(result.healthy?).to eq(true) - expect(result.to_h).to eq(expected_summary) - expect(result.as_json).to eq(expected_summary.as_json) - end - end - - context 'when there is a job that has not run' do - it 'returns an unhealthy summary' do - create(:job_run, job_name: 'test job 1', created_at: 16.minutes.ago) - create(:job_run, job_name: 'test job 2', created_at: 20.minutes.ago) - - expected_summary = { healthy: false, result: { 'test job 1' => false, 'test job 2' => true } } - - result = described_class.check - - expect(result.healthy?).to eq(false) - expect(result.to_h).to eq(expected_summary) - expect(result.as_json).to eq(expected_summary.as_json) - end - end -end diff --git a/spec/services/job_runner/job_run_needed_resolver_spec.rb b/spec/services/job_runner/job_run_needed_resolver_spec.rb deleted file mode 100644 index f48d0c265f7..00000000000 --- a/spec/services/job_runner/job_run_needed_resolver_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'rails_helper' - -describe JobRunner::JobRunNeededResolver do - let(:job_configuration) do - JobRunner::JobConfiguration.new( - name: 'Send GPO letter', - interval: 5 * 60, - timeout: 60, - callback: -> { 'Hello!' }, - ) - end - - subject { described_class.new(job_configuration) } - - describe '#new_job_needs_to_run?' do - context 'no jobs have been run ever' do - it { expect(subject.new_job_needs_to_run?).to eq(true) } - end - - context 'a job has been run within the interval' do - let!(:job_run) { create(:job_run, created_at: 4.minutes.ago) } - - it { expect(subject.new_job_needs_to_run?).to eq(false) } - end - - context 'a job has been run outside the interval' do - let!(:job_run) { create(:job_run, created_at: 6.minutes.ago) } - - it { expect(subject.new_job_needs_to_run?).to eq(true) } - end - - context 'a job with a different name has been run within the interval' do - let!(:job_run) { create(:job_run, created_at: 4.minutes.ago, job_name: 'different job') } - - it { expect(subject.new_job_needs_to_run?).to eq(true) } - end - end -end diff --git a/spec/services/job_runner/lock_referee_spec.rb b/spec/services/job_runner/lock_referee_spec.rb deleted file mode 100644 index 1b64aedc333..00000000000 --- a/spec/services/job_runner/lock_referee_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'rails_helper' - -describe JobRunner::LockReferee do - describe '#acquire_lock_and_run_callback_if_needed' do - let(:job_configuration) do - JobRunner::JobConfiguration.new( - name: 'Send GPO letter', - interval: 5 * 60, - timeout: 60, - callback: -> { 'Hello!' }, - ) - end - - subject { described_class.new(job_configuration) } - - context 'when a job has run recently' do - let!(:job_run) { create(:job_run, created_at: 1.minute.ago) } - - it 'does nothing' do - # It should not try to acquire a lock - expect(JobRun).to_not receive(:with_lock) - - subject.acquire_lock_and_run_callback_if_needed - - # It should not modify the existing job or create a new one - expect(job_run).to eq(JobRun.find(job_run.id)) - expect(JobRun.count).to eq(1) - end - end - - context 'when another thread wins the race and acquires a lock' do - it 'does not run a job' do - job_run = nil - expect(JobRun).to receive(:with_lock) do |&block| - # Simulate another job getting the lock and creating a job run - job_run = create(:job_run, created_at: 1.minute.ago) - block.call - end - - subject.acquire_lock_and_run_callback_if_needed - - # It should not modify the existing job or create a new one - expect(job_run).to eq(JobRun.find(job_run.id)) - expect(JobRun.count).to eq(1) - end - end - - context 'when this thread wins the race' do - it 'creates a JobRun and runs the callback' do - # It should try to acquire a lock - expect(JobRun).to receive(:with_lock).and_call_original - - subject.acquire_lock_and_run_callback_if_needed - - # It should have created a job with the result from the callback - expect(JobRun.count).to eq(1) - expect(JobRun.first.result).to eq('Hello!') - end - end - end -end diff --git a/spec/services/job_runner/runner_spec.rb b/spec/services/job_runner/runner_spec.rb deleted file mode 100644 index f0a5f8b103a..00000000000 --- a/spec/services/job_runner/runner_spec.rb +++ /dev/null @@ -1,127 +0,0 @@ -require 'rails_helper' - -describe JobRunner::Runner do - before do - described_class.clear_configurations - described_class.add_config JobRunner::JobConfiguration.new( - name: 'test job 1', - interval: 5 * 60, - timeout: 60, - callback: -> { 'test job 1 result' }, - ) - described_class.add_config JobRunner::JobConfiguration.new( - name: 'test job 2', - interval: 60 * 60, - timeout: 60 * 30, - callback: -> { 'test job 2 result' }, - ) - end - - describe '.configurations' do - it 'has the expected configurations' do - expect(described_class.configurations.length).to eq 2 - end - - it 'freezes the result array' do - expect { described_class.configurations << 123 }.to raise_error(FrozenError) - end - end - - describe '.disabled_jobs' do - it 'parses disabled job JSON' do - expect(described_class.disabled_jobs).to eq ['disabled job'] - end - end - - describe '.add_config' do - it 'rejects unexpected classes' do - expect { described_class.add_config 123 }.to raise_error(ArgumentError) - expect { described_class.add_config 'some job' }.to raise_error(ArgumentError) - end - - it 'adds a job to the configurations list' do - config = JobRunner::JobConfiguration.new( - name: 'test job 3', - interval: 60 * 60, - timeout: 60 * 30, - callback: -> { 'test job 3 result' }, - ) - - expect(described_class.configurations.length).to eq 2 - described_class.add_config(config) - expect(described_class.configurations.length).to eq 3 - expect(described_class.configurations.last).to eq config - end - - it 'is an alias of add_configuration' do - expect(described_class.method(:add_config)).to eq described_class.method(:add_configuration) - end - - it 'ignores disabled jobs' do - disabled_job = JobRunner::JobConfiguration.new( - name: 'disabled job', - interval: 60, - callback: -> { 'blah' }, - ) - - expect(described_class.configurations.length).to eq 2 - expect(described_class.add_config(disabled_job)).to eq false - expect(described_class.configurations.length).to eq 2 - end - end - - describe '#run' do - it 'runs the jobs in the configuration' do - subject.run - - expect(JobRun.count).to eq(2) - - first_job = JobRun.find_by(job_name: 'test job 1') - expect(first_job.result).to eq('test job 1 result') - - second_job = JobRun.find_by(job_name: 'test job 2') - expect(second_job.result).to eq('test job 2 result') - end - - context 'when there are jobs that are not due to run' do - it 'only runs the jobs that are due to run' do - previous_job_start = 20.minutes.ago - create(:job_run, job_name: 'test job 2', created_at: previous_job_start) - - subject.run - - expect(JobRun.count).to eq(2) - - first_job = JobRun.find_by(job_name: 'test job 1') - expect(first_job.result).to eq('test job 1 result') - - second_job = JobRun.find_by(job_name: 'test job 2') - expect(second_job.created_at).to be_within(1.second).of(previous_job_start) - end - end - - context 'when there are timed out jobs' do - it 'cleans up the timed out jobs' do - timed_out_job_start = 120.minutes.ago - create(:job_run, job_name: 'test job 2', created_at: timed_out_job_start) - - subject.run - - expect(JobRun.count).to eq(3) - - first_job = JobRun.find_by(job_name: 'test job 1') - expect(first_job.result).to eq('test job 1 result') - - timed_out_job, second_job = JobRun.where(job_name: 'test job 2'). - order(created_at: :asc).to_a - - expect(timed_out_job.result).to eq(nil) - expect(timed_out_job.finish_time).to eq(nil) - expect(timed_out_job.error).to eq('Timeout') - expect(timed_out_job.created_at).to be_within(1.second).of(timed_out_job_start) - - expect(second_job.result).to eq('test job 2 result') - end - end - end -end From 861a5160e450fbfcead29f4371585c66d345073f Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Thu, 14 Oct 2021 15:50:59 -0700 Subject: [PATCH 2/6] remove ruby_workers_cron_enabled config, its now always on --- config/application.yml.default | 1 - lib/identity_config.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/config/application.yml.default b/config/application.yml.default index d7e066ed068..c39ea6fc2fc 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -180,7 +180,6 @@ risc_notifications_active_job_enabled: 'false' risc_notifications_rate_limit_interval: '60' risc_notifications_rate_limit_max_requests: '1000' risc_notifications_rate_limit_overrides: '{"https://example.com/push":{"interval":120,"max_requests":10000}}' -ruby_workers_cron_enabled: 'true' ruby_workers_idv_enabled: 'true' rules_of_use_horizon_years: '6' rules_of_use_updated_at: '2021-05-21T00:00:00Z' diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 98757cdf49b..8f015df7323 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -250,7 +250,6 @@ def self.build_store(config_map) config.add(:risc_notifications_rate_limit_interval, type: :integer) config.add(:risc_notifications_rate_limit_max_requests, type: :integer) config.add(:risc_notifications_rate_limit_overrides, type: :json) - config.add(:ruby_workers_cron_enabled, type: :boolean) config.add(:ruby_workers_idv_enabled, type: :boolean) config.add(:rules_of_use_horizon_years, type: :integer) config.add(:rules_of_use_updated_at, type: :timestamp) From b13532059748bc90311b329820ca45950f89a79a Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Thu, 14 Oct 2021 15:51:47 -0700 Subject: [PATCH 3/6] add removal note --- bin/job_runs.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/job_runs.sh b/bin/job_runs.sh index 54533669f29..8376ca80b3c 100755 --- a/bin/job_runs.sh +++ b/bin/job_runs.sh @@ -1,4 +1,5 @@ #!/bin/bash set -euo pipefail +# This file can be removed when we remove the service that calls from devops sleep 100 From 38c7dcb9d92271fec4b089f93d13b662360ebe9e Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Fri, 15 Oct 2021 10:24:54 -0700 Subject: [PATCH 4/6] remove health job controller --- .../controllers/health/job_controller_spec.rb | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 spec/controllers/health/job_controller_spec.rb diff --git a/spec/controllers/health/job_controller_spec.rb b/spec/controllers/health/job_controller_spec.rb deleted file mode 100644 index 4fe3561255d..00000000000 --- a/spec/controllers/health/job_controller_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -require 'rails_helper' - -RSpec.describe Health::JobsController do - describe '#index' do - subject(:action) { get :index } - - context 'when jobs are healthy' do - it 'returns healthy' do - allow(JobRunner::HealthChecker).to receive(:check). - and_return(HealthCheckSummary.new(healthy: true, result: { 'foo' => true })) - - action - - expect(response.status).to eq(200) - - json = JSON.parse(response.body) - - expect(json['healthy']).to eq(true) - expect(json['result']).to eq({ 'foo' => true }) - end - end - - context 'when jobs are unhealthy' do - before do - expect(JobRunner::HealthChecker).to receive(:check). - and_return(HealthCheckSummary.new(healthy: false, result: { 'foo' => false })) - end - - it 'is a 500' do - action - - expect(response.status).to eq(500) - end - - it 'renders the error' do - action - - json = JSON.parse(response.body, symbolize_names: true) - - expect(json[:healthy]).to eq(false) - expect(json[:result]).to eq({ foo: false }) - end - end - end -end From 72e22601f817e3b61ca0cf2308e8419f24f3f0c1 Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Fri, 15 Oct 2021 10:26:02 -0700 Subject: [PATCH 5/6] lints --- config/initializers/job_configurations.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/initializers/job_configurations.rb b/config/initializers/job_configurations.rb index fe06c85d493..00153350f38 100644 --- a/config/initializers/job_configurations.rb +++ b/config/initializers/job_configurations.rb @@ -8,6 +8,7 @@ if defined?(Rails::Console) Rails.logger.info 'job_configurations: console detected, skipping schedule' else + # rubocop:disable Metrics/BlockLength Rails.application.configure do config.good_job.cron = { # Daily GPO letter mailings @@ -179,12 +180,13 @@ args: -> { [Time.zone.now] }, }, # Queue heartbeat job to GoodJob - heartbeat_job: { + heartbeat_job: { class: 'HeartbeatJob', cron: cron_5m, - } + }, } end + # rubocop:enable Metrics/BlockLength Rails.logger.info 'job_configurations: jobs scheduled with good_job.cron' end From 672b3109d976122d68004152aee894c2598b5da8 Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Fri, 15 Oct 2021 10:51:00 -0700 Subject: [PATCH 6/6] clean up tests --- spec/controllers/health/health_controller_spec.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spec/controllers/health/health_controller_spec.rb b/spec/controllers/health/health_controller_spec.rb index d78b40aa23d..c15bf85e7d1 100644 --- a/spec/controllers/health/health_controller_spec.rb +++ b/spec/controllers/health/health_controller_spec.rb @@ -7,8 +7,6 @@ allow(DatabaseHealthChecker).to receive(:simple_query).and_return('foo') allow(AccountResetHealthChecker).to receive(:check). and_return(HealthCheckSummary.new(healthy: true, result: 'foo')) - allow(JobRunner::HealthCheckerCritical).to receive(:check). - and_return(HealthCheckSummary.new(healthy: true, result: 'foo')) get :index json = JSON.parse(response.body, symbolize_names: true) @@ -26,8 +24,6 @@ and_raise(RuntimeError.new('canceling statement due to statement timeout')) allow(AccountResetHealthChecker).to receive(:check). and_return(HealthCheckSummary.new(healthy: true, result: 'foo')) - allow(JobRunner::HealthCheckerCritical).to receive(:check). - and_return(HealthCheckSummary.new(healthy: true, result: 'foo')) get :index json = JSON.parse(response.body, symbolize_names: true) @@ -46,8 +42,6 @@ and_raise(RuntimeError.new('canceling statement due to statement timeout')) allow(AccountResetHealthChecker).to receive(:check). and_return(HealthCheckSummary.new(healthy: false, result: 'foo')) - allow(JobRunner::HealthCheckerCritical).to receive(:check). - and_return(HealthCheckSummary.new(healthy: false, result: 'foo')) get :index json = JSON.parse(response.body, symbolize_names: true)