# frozen_string_literal: true module GoodJob class Setting < BaseRecord CRON_KEYS_ENABLED = "cron_keys_enabled" CRON_KEYS_DISABLED = "cron_keys_disabled" PAUSES = "pauses" self.table_name = 'good_job_settings' self.implicit_order_column = 'created_at' def self.cron_key_enabled?(key, default: true) if default cron_disabled = find_by(key: CRON_KEYS_DISABLED)&.value || [] cron_disabled.exclude?(key.to_s) else cron_enabled = find_by(key: CRON_KEYS_ENABLED)&.value || [] cron_enabled.include?(key.to_s) end end def self.cron_key_enable(key) key_string = key.to_s enabled_setting = find_or_initialize_by(key: CRON_KEYS_ENABLED) do |record| record.value = [] end enabled_setting.value << key unless enabled_setting.value.include?(key_string) enabled_setting.save! disabled_setting = GoodJob::Setting.find_by(key: CRON_KEYS_DISABLED) return unless disabled_setting&.value&.include?(key_string) disabled_setting.value.delete(key_string) disabled_setting.save! end def self.cron_key_disable(key) enabled_setting = GoodJob::Setting.find_by(key: CRON_KEYS_ENABLED) key_string = key.to_s if enabled_setting&.value&.include?(key_string) enabled_setting.value.delete(key_string) enabled_setting.save! end disabled_setting = find_or_initialize_by(key: CRON_KEYS_DISABLED) do |record| record.value = [] end disabled_setting.value << key unless disabled_setting.value.include?(key_string) disabled_setting.save! end def self.pause(queue: nil, job_class: nil, label: nil) raise ArgumentError, "Must provide exactly one of queue, job_class, or label" unless [queue, job_class, label].count(&:present?) == 1 setting = find_or_initialize_by(key: PAUSES) do |record| record.value = { "queues" => [], "job_classes" => [], "labels" => [] } end if queue setting.value["queues"] ||= [] setting.value["queues"] << queue.to_s unless setting.value["queues"].include?(queue.to_s) elsif job_class setting.value["job_classes"] ||= [] setting.value["job_classes"] << job_class.to_s unless setting.value["job_classes"].include?(job_class.to_s) else setting.value["labels"] ||= [] setting.value["labels"] << label.to_s unless setting.value["labels"].include?(label.to_s) end setting.save! end def self.unpause(queue: nil, job_class: nil, label: nil) raise ArgumentError, "Must provide exactly one of queue, job_class, or label" unless [queue, job_class, label].count(&:present?) == 1 setting = find_by(key: PAUSES) return unless setting if queue return unless setting.value["queues"]&.include?(queue.to_s) setting.value["queues"].delete(queue.to_s) elsif job_class return unless setting.value["job_classes"]&.include?(job_class.to_s) setting.value["job_classes"].delete(job_class.to_s) else return unless setting.value["labels"]&.include?(label.to_s) setting.value["labels"].delete(label.to_s) end setting.save! end def self.paused?(queue: nil, job_class: nil, label: nil) raise ArgumentError, "Must provide at most one of queue, job_class, or label" if [queue, job_class, label].count(&:present?) > 1 if queue queue.in? paused(:queues) elsif job_class job_class.in? paused(:job_classes) elsif label label.in? paused(:labels) else paused.values.any?(&:any?) end end def self.paused(type = nil) setting = find_by(key: PAUSES) pauses = setting&.value&.deep_dup || { "queues" => [], "job_classes" => [], "labels" => [] } pauses = pauses.with_indifferent_access case type when :queues pauses["queues"] when :job_classes pauses["job_classes"] when :labels pauses["labels"] else { queues: pauses["queues"] || [], job_classes: pauses["job_classes"] || [], labels: pauses["labels"] || [], } end end end end