diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index e289c9898ee..c50ef3fd87f 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -10,6 +10,14 @@ class GetUspsProofingResultsJob < ApplicationJob ] queue_as :default + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: 'get_usps_proofing_results', + ) + + discard_on GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError def email_analytics_attributes(enrollment) { diff --git a/app/jobs/gpo_daily_job.rb b/app/jobs/gpo_daily_job.rb index f913744be5e..26834e0aefb 100644 --- a/app/jobs/gpo_daily_job.rb +++ b/app/jobs/gpo_daily_job.rb @@ -1,6 +1,15 @@ class GpoDailyJob < ApplicationJob queue_as :low + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "gpo-daily-job-#{arguments.first}" }, + ) + + discard_on GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError + # Enqueue a test letter every day, but only upload letters on working weekdays def perform(date) GpoDailyTestSender.new.run diff --git a/app/jobs/phone_number_opt_out_sync_job.rb b/app/jobs/phone_number_opt_out_sync_job.rb index a1f67341c8e..05b7ef4bcbc 100644 --- a/app/jobs/phone_number_opt_out_sync_job.rb +++ b/app/jobs/phone_number_opt_out_sync_job.rb @@ -1,5 +1,14 @@ class PhoneNumberOptOutSyncJob < ApplicationJob queue_as :long_running + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> do + rounded = TimeService.round_time(time: arguments.first, interval: 1.hour) + "phone-number-opt-out-sync-#{rounded.to_i}" + end, + ) def perform(_now) all_phone_numbers = Set.new diff --git a/app/jobs/psql_stats_job.rb b/app/jobs/psql_stats_job.rb index a6bf42e1df6..2fdeb58174a 100644 --- a/app/jobs/psql_stats_job.rb +++ b/app/jobs/psql_stats_job.rb @@ -1,5 +1,16 @@ class PsqlStatsJob < ApplicationJob queue_as :default + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> do + rounded = TimeService.round_time(time: arguments.first, interval: 1.minute) + "psql_bloat_statistics-#{rounded.to_i}" + end, + ) + + discard_on GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError # gather data on bloat for each table # https://github.com/ioguix/pgsql-bloat-estimation/blob/master/table/table_bloat.sql diff --git a/app/jobs/reports/agency_invoice_iaa_supplement_report.rb b/app/jobs/reports/agency_invoice_iaa_supplement_report.rb index 4010f6f9d8d..bd222154b83 100644 --- a/app/jobs/reports/agency_invoice_iaa_supplement_report.rb +++ b/app/jobs/reports/agency_invoice_iaa_supplement_report.rb @@ -2,6 +2,13 @@ module Reports class AgencyInvoiceIaaSupplementReport < BaseReport REPORT_NAME = 'agency-invoice-iaa-supplemement-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) raw_results = IaaReportingHelper.iaas.flat_map do |iaa| Db::MonthlySpAuthCount::UniqueMonthlyAuthCountsByIaa.call( diff --git a/app/jobs/reports/agency_invoice_issuer_supplement_report.rb b/app/jobs/reports/agency_invoice_issuer_supplement_report.rb index a8f6bff1cfe..d825d42e914 100644 --- a/app/jobs/reports/agency_invoice_issuer_supplement_report.rb +++ b/app/jobs/reports/agency_invoice_issuer_supplement_report.rb @@ -2,6 +2,13 @@ module Reports class AgencyInvoiceIssuerSupplementReport < BaseReport REPORT_NAME = 'agency-invoice-issuer-supplemement-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) raw_results = service_providers.flat_map do |service_provider| transaction_with_timeout do diff --git a/app/jobs/reports/agency_user_counts_report.rb b/app/jobs/reports/agency_user_counts_report.rb index e37488b6f4f..10524f201ad 100644 --- a/app/jobs/reports/agency_user_counts_report.rb +++ b/app/jobs/reports/agency_user_counts_report.rb @@ -4,6 +4,13 @@ module Reports class AgencyUserCountsReport < BaseReport REPORT_NAME = 'agency-user-counts-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) user_counts = transaction_with_timeout do Db::AgencyIdentity::AgencyUserCounts.call diff --git a/app/jobs/reports/agreement_summary_report.rb b/app/jobs/reports/agreement_summary_report.rb index f7fef643f1d..bbee6361f40 100644 --- a/app/jobs/reports/agreement_summary_report.rb +++ b/app/jobs/reports/agreement_summary_report.rb @@ -4,6 +4,13 @@ module Reports class AgreementSummaryReport < BaseReport REPORT_NAME = 'agreement-summary-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) csv = build_report diff --git a/app/jobs/reports/base_report.rb b/app/jobs/reports/base_report.rb index 23e6f71cb99..c984d3d0219 100644 --- a/app/jobs/reports/base_report.rb +++ b/app/jobs/reports/base_report.rb @@ -4,6 +4,9 @@ module Reports class BaseReport < ApplicationJob queue_as :long_running + # We use good_job's concurrency features to cancel "extra" or duplicative runs of the same job + discard_on GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError + def self.transaction_with_timeout(rails_env = Rails.env) # rspec-rails's use_transactional_tests does not seem to act as expected when switching # connections mid-test, so we just skip for now :[ diff --git a/app/jobs/reports/combined_invoice_supplement_report.rb b/app/jobs/reports/combined_invoice_supplement_report.rb index dea2a82843a..45d2dbe0c5d 100644 --- a/app/jobs/reports/combined_invoice_supplement_report.rb +++ b/app/jobs/reports/combined_invoice_supplement_report.rb @@ -4,6 +4,13 @@ module Reports class CombinedInvoiceSupplementReport < BaseReport REPORT_NAME = 'combined-invoice-supplement-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) iaas = IaaReportingHelper.iaas diff --git a/app/jobs/reports/daily_auths_report.rb b/app/jobs/reports/daily_auths_report.rb index 11c929bf5b9..b5dce921336 100644 --- a/app/jobs/reports/daily_auths_report.rb +++ b/app/jobs/reports/daily_auths_report.rb @@ -2,6 +2,13 @@ module Reports class DailyAuthsReport < BaseReport REPORT_NAME = 'daily-auths-report' + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + attr_reader :report_date def perform(report_date) diff --git a/app/jobs/reports/daily_dropoffs_report.rb b/app/jobs/reports/daily_dropoffs_report.rb index 5628cabdfd0..52fa0dd03c9 100644 --- a/app/jobs/reports/daily_dropoffs_report.rb +++ b/app/jobs/reports/daily_dropoffs_report.rb @@ -4,6 +4,13 @@ module Reports class DailyDropoffsReport < BaseReport REPORT_NAME = 'daily-dropoffs-report' + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + attr_reader :report_date def perform(report_date) diff --git a/app/jobs/reports/deleted_user_accounts_report.rb b/app/jobs/reports/deleted_user_accounts_report.rb index 5bdd18925d4..f1e508f6b04 100644 --- a/app/jobs/reports/deleted_user_accounts_report.rb +++ b/app/jobs/reports/deleted_user_accounts_report.rb @@ -5,6 +5,13 @@ module Reports class DeletedUserAccountsReport < BaseReport REPORT_NAME = 'deleted-user-accounts-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) configs = IdentityConfig.store.deleted_user_accounts_report_configs configs.each do |report_hash| diff --git a/app/jobs/reports/doc_auth_drop_off_rates_per_sprint_report.rb b/app/jobs/reports/doc_auth_drop_off_rates_per_sprint_report.rb index 44a11b16a5d..9f60736b64c 100644 --- a/app/jobs/reports/doc_auth_drop_off_rates_per_sprint_report.rb +++ b/app/jobs/reports/doc_auth_drop_off_rates_per_sprint_report.rb @@ -5,6 +5,13 @@ class DocAuthDropOffRatesPerSprintReport < BaseReport REPORT_NAME = 'doc-auth-drop-offs-per-sprint-report'.freeze FIRST_SPRINT_DATE = '10-10-2019'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) ret = generate_report save_report(REPORT_NAME, ret.join, extension: 'txt') diff --git a/app/jobs/reports/doc_auth_drop_off_rates_report.rb b/app/jobs/reports/doc_auth_drop_off_rates_report.rb index c9ae6f76396..5b43d713e22 100644 --- a/app/jobs/reports/doc_auth_drop_off_rates_report.rb +++ b/app/jobs/reports/doc_auth_drop_off_rates_report.rb @@ -4,6 +4,13 @@ module Reports class DocAuthDropOffRatesReport < BaseReport REPORT_NAME = 'doc-auth-drop-off-rates-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) ret = generate_report save_report(REPORT_NAME, ret.join, extension: 'txt') diff --git a/app/jobs/reports/doc_auth_funnel_report.rb b/app/jobs/reports/doc_auth_funnel_report.rb index c330710f0fa..ac6b81d9b3e 100644 --- a/app/jobs/reports/doc_auth_funnel_report.rb +++ b/app/jobs/reports/doc_auth_funnel_report.rb @@ -4,6 +4,13 @@ module Reports class DocAuthFunnelReport < BaseReport REPORT_NAME = 'doc-auth-funnel-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) report = transaction_with_timeout do Db::DocAuthLog::DocAuthFunnelSummaryStats.new.call diff --git a/app/jobs/reports/gpo_report.rb b/app/jobs/reports/gpo_report.rb index bbc1a4c9bbd..c99a09f4075 100644 --- a/app/jobs/reports/gpo_report.rb +++ b/app/jobs/reports/gpo_report.rb @@ -4,6 +4,13 @@ module Reports class GpoReport < BaseReport REPORT_NAME = 'usps-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(today) @results = { today: today.to_s, diff --git a/app/jobs/reports/monthly_gpo_letter_requests_report.rb b/app/jobs/reports/monthly_gpo_letter_requests_report.rb index 3df8f434f47..fe9e24ee0e7 100644 --- a/app/jobs/reports/monthly_gpo_letter_requests_report.rb +++ b/app/jobs/reports/monthly_gpo_letter_requests_report.rb @@ -4,6 +4,13 @@ module Reports class MonthlyGpoLetterRequestsReport < BaseReport REPORT_NAME = 'monthly-usps-letter-requests-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date, start_time: first_of_this_month, end_time: end_of_today) daily_results = transaction_with_timeout do ::LetterRequestsToGpoFtpLog.where(ftp_at: start_time..end_time) diff --git a/app/jobs/reports/omb_fitara_report.rb b/app/jobs/reports/omb_fitara_report.rb index 3ef2efa5565..93f06eca58b 100644 --- a/app/jobs/reports/omb_fitara_report.rb +++ b/app/jobs/reports/omb_fitara_report.rb @@ -6,6 +6,13 @@ class OmbFitaraReport < BaseReport MOST_RECENT_MONTHS_COUNT = 2 REPORT_NAME = 'omb-fitara-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) results = transaction_with_timeout do report_hash diff --git a/app/jobs/reports/proofing_costs_report.rb b/app/jobs/reports/proofing_costs_report.rb index 1dcaea1b80a..50686c1ce7f 100644 --- a/app/jobs/reports/proofing_costs_report.rb +++ b/app/jobs/reports/proofing_costs_report.rb @@ -4,6 +4,13 @@ module Reports class ProofingCostsReport < BaseReport REPORT_NAME = 'proofing-costs-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) report = transaction_with_timeout do Db::ProofingCost::ProofingCostsSummary.new.call diff --git a/app/jobs/reports/sp_active_users_over_period_of_performance_report.rb b/app/jobs/reports/sp_active_users_over_period_of_performance_report.rb index d91f7350f24..dc3294034b8 100644 --- a/app/jobs/reports/sp_active_users_over_period_of_performance_report.rb +++ b/app/jobs/reports/sp_active_users_over_period_of_performance_report.rb @@ -4,6 +4,13 @@ module Reports class SpActiveUsersOverPeriodOfPerformanceReport < BaseReport REPORT_NAME = 'sp-active-users-over-period-of-performance-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) results = transaction_with_timeout do Db::Identity::SpActiveUserCountsWithinIaaWindow.call diff --git a/app/jobs/reports/sp_active_users_report.rb b/app/jobs/reports/sp_active_users_report.rb index 184ae184140..fed2365f6c8 100644 --- a/app/jobs/reports/sp_active_users_report.rb +++ b/app/jobs/reports/sp_active_users_report.rb @@ -4,6 +4,13 @@ module Reports class SpActiveUsersReport < BaseReport REPORT_NAME = 'sp-active-users-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + # This daily job captures the total number of active users per SP from the beginning of the the # current fiscal year until now. # diff --git a/app/jobs/reports/sp_cost_report.rb b/app/jobs/reports/sp_cost_report.rb index 1b56b8b83e4..63d906e786a 100644 --- a/app/jobs/reports/sp_cost_report.rb +++ b/app/jobs/reports/sp_cost_report.rb @@ -4,6 +4,13 @@ module Reports class SpCostReport < BaseReport REPORT_NAME = 'sp-cost-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) results = transaction_with_timeout do Db::SpCost::SpCostSummary.call(first_of_this_month, end_of_today) diff --git a/app/jobs/reports/sp_user_counts_report.rb b/app/jobs/reports/sp_user_counts_report.rb index 64e8e76cc04..9e65818b727 100644 --- a/app/jobs/reports/sp_user_counts_report.rb +++ b/app/jobs/reports/sp_user_counts_report.rb @@ -4,6 +4,13 @@ module Reports class SpUserCountsReport < BaseReport REPORT_NAME = 'sp-user-counts-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) user_counts = transaction_with_timeout do Db::Identity::SpUserCounts.call diff --git a/app/jobs/reports/sp_user_quotas_report.rb b/app/jobs/reports/sp_user_quotas_report.rb index 49862c55a39..ea665425a41 100644 --- a/app/jobs/reports/sp_user_quotas_report.rb +++ b/app/jobs/reports/sp_user_quotas_report.rb @@ -4,6 +4,13 @@ module Reports class SpUserQuotasReport < BaseReport REPORT_NAME = 'sp-user-quotas-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) results = run_report_and_save_to_s3 update_quota_limit_cache diff --git a/app/jobs/reports/total_ial2_costs_report.rb b/app/jobs/reports/total_ial2_costs_report.rb index 071133d3b79..9219908761a 100644 --- a/app/jobs/reports/total_ial2_costs_report.rb +++ b/app/jobs/reports/total_ial2_costs_report.rb @@ -5,6 +5,13 @@ class TotalIal2CostsReport < BaseReport REPORT_NAME = 'total-ial2-costs'.freeze NUM_LOOKBACK_DAYS = 45 + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(date) results = transaction_with_timeout { query(date) } diff --git a/app/jobs/reports/total_monthly_auths_report.rb b/app/jobs/reports/total_monthly_auths_report.rb index 441dc7139af..0cd9675fd88 100644 --- a/app/jobs/reports/total_monthly_auths_report.rb +++ b/app/jobs/reports/total_monthly_auths_report.rb @@ -4,6 +4,13 @@ module Reports class TotalMonthlyAuthsReport < BaseReport REPORT_NAME = 'total-monthly-auths-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) auth_counts = transaction_with_timeout do Db::MonthlySpAuthCount::TotalMonthlyAuthCounts.call diff --git a/app/jobs/reports/total_sp_cost_report.rb b/app/jobs/reports/total_sp_cost_report.rb index efef09a6722..dc171ce7529 100644 --- a/app/jobs/reports/total_sp_cost_report.rb +++ b/app/jobs/reports/total_sp_cost_report.rb @@ -4,6 +4,13 @@ module Reports class TotalSpCostReport < BaseReport REPORT_NAME = 'total-sp-cost-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(_date) auth_counts = transaction_with_timeout do Db::SpCost::TotalSpCostSummary.call(first_of_this_month, end_of_today) diff --git a/app/jobs/reports/verification_failures_report.rb b/app/jobs/reports/verification_failures_report.rb index 90cf4d511be..1673ed6a297 100644 --- a/app/jobs/reports/verification_failures_report.rb +++ b/app/jobs/reports/verification_failures_report.rb @@ -6,6 +6,13 @@ module Reports class VerificationFailuresReport < BaseReport REPORT_NAME = 'verification-failures-report'.freeze + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "#{REPORT_NAME}-#{arguments.first}" }, + ) + def perform(date) csv_reports = [] configs = IdentityConfig.store.verification_errors_report_configs diff --git a/app/services/account_reset/grant_requests_and_send_emails.rb b/app/services/account_reset/grant_requests_and_send_emails.rb index 86b0e886a72..f6e1f119570 100644 --- a/app/services/account_reset/grant_requests_and_send_emails.rb +++ b/app/services/account_reset/grant_requests_and_send_emails.rb @@ -2,6 +2,18 @@ module AccountReset class GrantRequestsAndSendEmails < ApplicationJob queue_as :low + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> do + rounded = TimeService.round_time(time: arguments.first, interval: 5.minutes) + "grant-requests-and-send-emails-#{rounded.to_i}" + end, + ) + + discard_on GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError + def perform(now) notifications_sent = 0 AccountResetRequest.where( diff --git a/app/services/agreements/reports/partner_api_report.rb b/app/services/agreements/reports/partner_api_report.rb index 8b772eb782b..20ebea72142 100644 --- a/app/services/agreements/reports/partner_api_report.rb +++ b/app/services/agreements/reports/partner_api_report.rb @@ -3,6 +3,15 @@ module Reports class PartnerApiReport < ApplicationJob queue_as :low + include GoodJob::ActiveJobExtensions::Concurrency + + good_job_control_concurrency_with( + total_limit: 1, + key: -> { "partner-api-report-#{arguments.first}" }, + ) + + discard_on GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError + def perform(_date) return unless IdentityConfig.store.enable_partner_api diff --git a/config/application.rb b/config/application.rb index bb9f84bcbd2..80cb04b5fad 100644 --- a/config/application.rb +++ b/config/application.rb @@ -69,7 +69,7 @@ class Application < Rails::Application config.good_job.enable_cron = true config.good_job.max_threads = IdentityConfig.store.good_job_max_threads config.good_job.queues = IdentityConfig.store.good_job_queues - config.good_job.preserve_job_records = false + config.good_job.preserve_job_records = true config.good_job.queue_select_limit = IdentityConfig.store.good_job_queue_select_limit # see config/initializers/job_configurations.rb for cron schedule diff --git a/spec/jobs/gpo_daily_job_spec.rb b/spec/jobs/gpo_daily_job_spec.rb index 84b13ff7db3..14ae4c683ee 100644 --- a/spec/jobs/gpo_daily_job_spec.rb +++ b/spec/jobs/gpo_daily_job_spec.rb @@ -48,4 +48,13 @@ end end end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key).to eq("gpo-daily-job-#{date}") + end + end end diff --git a/spec/jobs/phone_number_opt_out_sync_job_spec.rb b/spec/jobs/phone_number_opt_out_sync_job_spec.rb index 82572faf50a..d10a6e318cc 100644 --- a/spec/jobs/phone_number_opt_out_sync_job_spec.rb +++ b/spec/jobs/phone_number_opt_out_sync_job_spec.rb @@ -32,4 +32,19 @@ end end end + + describe '#good_job_concurrency_key' do + it 'is the job name and the current time, rounded to the nearest hour' do + now = Time.zone.at(1629817200) + + job_now = PhoneNumberOptOutSyncJob.new(now) + expect(job_now.good_job_concurrency_key).to eq("phone-number-opt-out-sync-#{now.to_i}") + + job_plus_30m = PhoneNumberOptOutSyncJob.new(now + 30.minutes) + expect(job_plus_30m.good_job_concurrency_key).to eq(job_now.good_job_concurrency_key) + + job_plus_1h = PhoneNumberOptOutSyncJob.new(now + 1.hour) + expect(job_plus_1h.good_job_concurrency_key).to_not eq(job_now.good_job_concurrency_key) + end + end end diff --git a/spec/jobs/reports/agency_invoice_iaa_supplement_report_spec.rb b/spec/jobs/reports/agency_invoice_iaa_supplement_report_spec.rb index c5b3c98ec88..8feac5fac06 100644 --- a/spec/jobs/reports/agency_invoice_iaa_supplement_report_spec.rb +++ b/spec/jobs/reports/agency_invoice_iaa_supplement_report_spec.rb @@ -258,4 +258,14 @@ def build_integration(issuer:, partner_account:) partner_account: partner_account, ) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/agency_invoice_issuer_supplement_report_spec.rb b/spec/jobs/reports/agency_invoice_issuer_supplement_report_spec.rb index 3b5c3a209f0..ff602ace3c4 100644 --- a/spec/jobs/reports/agency_invoice_issuer_supplement_report_spec.rb +++ b/spec/jobs/reports/agency_invoice_issuer_supplement_report_spec.rb @@ -66,4 +66,14 @@ end end end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/agency_user_counts_report_spec.rb b/spec/jobs/reports/agency_user_counts_report_spec.rb index 838e4716a70..8c60a48ba6b 100644 --- a/spec/jobs/reports/agency_user_counts_report_spec.rb +++ b/spec/jobs/reports/agency_user_counts_report_spec.rb @@ -16,4 +16,14 @@ expect(subject.perform(Time.zone.today)).to eq(result) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/agreement_summary_report_spec.rb b/spec/jobs/reports/agreement_summary_report_spec.rb index c32711aec18..aaab1f5cbaf 100644 --- a/spec/jobs/reports/agreement_summary_report_spec.rb +++ b/spec/jobs/reports/agreement_summary_report_spec.rb @@ -78,4 +78,14 @@ end end end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/combined_invoice_supplement_report_spec.rb b/spec/jobs/reports/combined_invoice_supplement_report_spec.rb index 9ef5279b3c6..9f7ab9ea9e7 100644 --- a/spec/jobs/reports/combined_invoice_supplement_report_spec.rb +++ b/spec/jobs/reports/combined_invoice_supplement_report_spec.rb @@ -215,4 +215,14 @@ def build_integration(issuer:, partner_account:) partner_account: partner_account, ) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/daily_auths_report_spec.rb b/spec/jobs/reports/daily_auths_report_spec.rb index f7023a4acc6..0d3d82453bc 100644 --- a/spec/jobs/reports/daily_auths_report_spec.rb +++ b/spec/jobs/reports/daily_auths_report_spec.rb @@ -108,4 +108,14 @@ end end end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/daily_dropoffs_report_spec.rb b/spec/jobs/reports/daily_dropoffs_report_spec.rb index c0f557fb7db..56221c74098 100644 --- a/spec/jobs/reports/daily_dropoffs_report_spec.rb +++ b/spec/jobs/reports/daily_dropoffs_report_spec.rb @@ -140,4 +140,14 @@ end end end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/deleted_user_accounts_report_spec.rb b/spec/jobs/reports/deleted_user_accounts_report_spec.rb index cfee9a085b7..c7457c8555e 100644 --- a/spec/jobs/reports/deleted_user_accounts_report_spec.rb +++ b/spec/jobs/reports/deleted_user_accounts_report_spec.rb @@ -38,4 +38,14 @@ subject.perform(Time.zone.today) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/gpo_report_spec.rb b/spec/jobs/reports/gpo_report_spec.rb index c5542f4e4c2..359e9e1e168 100644 --- a/spec/jobs/reports/gpo_report_spec.rb +++ b/spec/jobs/reports/gpo_report_spec.rb @@ -42,6 +42,16 @@ expect(JSON.parse(subject.perform(Time.zone.today))).to eq(one_letter_sent_and_verified_report) end + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end + def create_ucc_for(profile) GpoConfirmationCode.create( profile: profile, diff --git a/spec/jobs/reports/sp_active_users_over_period_of_performance_report_spec.rb b/spec/jobs/reports/sp_active_users_over_period_of_performance_report_spec.rb index 36db193672f..ad36992ce09 100644 --- a/spec/jobs/reports/sp_active_users_over_period_of_performance_report_spec.rb +++ b/spec/jobs/reports/sp_active_users_over_period_of_performance_report_spec.rb @@ -51,4 +51,14 @@ }], ) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/sp_active_users_report_spec.rb b/spec/jobs/reports/sp_active_users_report_spec.rb index 8bb4b8324ab..77b1d8f4629 100644 --- a/spec/jobs/reports/sp_active_users_report_spec.rb +++ b/spec/jobs/reports/sp_active_users_report_spec.rb @@ -79,6 +79,16 @@ expect(subject.perform(job_date)).to eq(result) end + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end + describe '#reporting_range' do it 'returns entire last fiscal year when it is October 1st' do job_date = Date.new(2022, 10, 1) diff --git a/spec/jobs/reports/sp_cost_report_spec.rb b/spec/jobs/reports/sp_cost_report_spec.rb index 51dd8f577ea..bc301c94bb3 100644 --- a/spec/jobs/reports/sp_cost_report_spec.rb +++ b/spec/jobs/reports/sp_cost_report_spec.rb @@ -35,4 +35,14 @@ }], ) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/sp_user_counts_report_spec.rb b/spec/jobs/reports/sp_user_counts_report_spec.rb index 70a2c1d9cea..4d818298ad1 100644 --- a/spec/jobs/reports/sp_user_counts_report_spec.rb +++ b/spec/jobs/reports/sp_user_counts_report_spec.rb @@ -65,4 +65,14 @@ expect(subject.perform(Time.zone.today)).to eq(result) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/sp_user_quotas_report_spec.rb b/spec/jobs/reports/sp_user_quotas_report_spec.rb index 52624c8ecd7..5d82b232ed6 100644 --- a/spec/jobs/reports/sp_user_quotas_report_spec.rb +++ b/spec/jobs/reports/sp_user_quotas_report_spec.rb @@ -32,4 +32,14 @@ def expect_report_to_run_correctly_for_fiscal_start_year_month_day(year, month, expect(subject.perform(Time.zone.today)).to eq(results) end end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/total_ial2_costs_report_spec.rb b/spec/jobs/reports/total_ial2_costs_report_spec.rb index b55f6075797..751c32fc192 100644 --- a/spec/jobs/reports/total_ial2_costs_report_spec.rb +++ b/spec/jobs/reports/total_ial2_costs_report_spec.rb @@ -68,4 +68,14 @@ report.perform(date) end end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/total_monthly_auths_report_spec.rb b/spec/jobs/reports/total_monthly_auths_report_spec.rb index edbe3217969..2a4ea5ffcfb 100644 --- a/spec/jobs/reports/total_monthly_auths_report_spec.rb +++ b/spec/jobs/reports/total_monthly_auths_report_spec.rb @@ -34,4 +34,14 @@ expect(subject.perform(Time.zone.today)).to eq(result) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/total_sp_cost_report_spec.rb b/spec/jobs/reports/total_sp_cost_report_spec.rb index 22cd8c1747d..60b0a3c5a5e 100644 --- a/spec/jobs/reports/total_sp_cost_report_spec.rb +++ b/spec/jobs/reports/total_sp_cost_report_spec.rb @@ -26,4 +26,14 @@ }], ) end + + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end end diff --git a/spec/jobs/reports/verification_failures_report_spec.rb b/spec/jobs/reports/verification_failures_report_spec.rb index 6e59db9d48c..bb291236642 100644 --- a/spec/jobs/reports/verification_failures_report_spec.rb +++ b/spec/jobs/reports/verification_failures_report_spec.rb @@ -195,6 +195,16 @@ expect(csv[1]).to eq([uuid, now.to_time.utc.iso8601, 'ABANDON']) end + describe '#good_job_concurrency_key' do + let(:date) { Time.zone.today } + + it 'is the job name and the date' do + job = described_class.new(date) + expect(job.good_job_concurrency_key). + to eq("#{described_class::REPORT_NAME}-#{date}") + end + end + def run_reports ServiceProvider.create(issuer: issuer, agency_id: 1, friendly_name: issuer) AgencyIdentity.create(agency_id: 1, user_id: user.id, uuid: uuid) diff --git a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb index 13b0344dd93..52cd3992664 100644 --- a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb +++ b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb @@ -70,6 +70,21 @@ end end + describe '#good_job_concurrency_key' do + it 'is the job name and the current time, rounded to the nearest 5 minutes' do + now = Time.zone.at(1629819000) + + job_now = AccountReset::GrantRequestsAndSendEmails.new(now) + expect(job_now.good_job_concurrency_key).to eq("grant-requests-and-send-emails-#{now.to_i}") + + job_plus_1m = AccountReset::GrantRequestsAndSendEmails.new(now + 1.minute) + expect(job_plus_1m.good_job_concurrency_key).to eq(job_now.good_job_concurrency_key) + + job_plus_5m = AccountReset::GrantRequestsAndSendEmails.new(now + 5.minutes) + expect(job_plus_5m.good_job_concurrency_key).to_not eq(job_now.good_job_concurrency_key) + end + end + def before_waiting_the_full_wait_period(now) days = IdentityConfig.store.account_reset_wait_period_days.days travel_to(now - 1 - days) do diff --git a/spec/services/agreements/reports/partner_api_report_spec.rb b/spec/services/agreements/reports/partner_api_report_spec.rb index edb7c5ead02..47f40ae2b13 100644 --- a/spec/services/agreements/reports/partner_api_report_spec.rb +++ b/spec/services/agreements/reports/partner_api_report_spec.rb @@ -14,4 +14,11 @@ expect(described_class.new.perform(today)).to eq(true) end end + + describe '#good_job_concurrency_key' do + it 'is the job name and the date' do + job = described_class.new(today) + expect(job.good_job_concurrency_key).to eq("partner-api-report-#{today}") + end + end end