class Resque::Plugins::DisableJob::Job
The Job
class contains the logic that determines if the current job is disabled, and methods to disable and enable a specific job.
Public Class Methods
disable_job(name, specific_args: {}, timeout: DEFAULT_TIMEOUT)
click to toggle source
To disable a job we need to add it in 3 data structures:
-
we need to add the job name to the main set so we know what jobs have rules
-
we add the arguments to the job's rule hash
-
we create a counter for the individual rule that will keep track of how many times it was matched
# File lib/resque/plugins/disable_job/job.rb, line 55 def self.disable_job(name, specific_args: {}, timeout: DEFAULT_TIMEOUT) rule = Rule.new(name, specific_args) Resque.redis.multi do Resque.redis.sadd rule.main_set, rule.job_name Resque.redis.hset(rule.all_rules_key, rule.digest, rule.serialized_arguments) Resque.redis.set(rule.rule_key, 0) Resque.redis.expire(rule.rule_key, timeout) end end
disabled?(job_name, job_args)
click to toggle source
disabled? checks if the job and it's arguments is disabled
# File lib/resque/plugins/disable_job/job.rb, line 12 def self.disabled?(job_name, job_args) # We get all the rules for the current job rules = get_all_rules(job_name) # We limit this to 10 rules for performance reasons. Each check delays the job from being performed matched_rule = match_rules(job_name, job_args, rules) if !matched_rule.nil? # if we found a matched rule, we record this and return true record_matched_rule(job_name, job_args, matched_rule) true else false end end
disabled_jobs()
click to toggle source
# File lib/resque/plugins/disable_job/job.rb, line 78 def self.disabled_jobs Resque.redis.smembers(Rule::JOBS_SET) end
enable_all(job_name)
click to toggle source
# File lib/resque/plugins/disable_job/job.rb, line 70 def self.enable_all(job_name) get_all_rules(job_name).map { |r| remove_specific_rule(r) } end
enable_all!()
click to toggle source
# File lib/resque/plugins/disable_job/job.rb, line 74 def self.enable_all! disabled_jobs.map { |job_name| enable_all(job_name) } end
enable_job(name, specific_args: {})
click to toggle source
To enable a job, we just need to remove it
# File lib/resque/plugins/disable_job/job.rb, line 66 def self.enable_job(name, specific_args: {}) remove_specific_rule(Rule.new(name, specific_args)) end
expired?(rule)
click to toggle source
The rule is expired if the TTL of the rule key is -1.
# File lib/resque/plugins/disable_job/job.rb, line 47 def self.expired?(rule) Resque.redis.ttl(rule.rule_key) < 0 # .negative? only works in Ruby 2.3 and above end
match_rules(job_name, job_args, rules)
click to toggle source
# File lib/resque/plugins/disable_job/job.rb, line 27 def self.match_rules(job_name, job_args, rules) rules.take(MAX_JOB_RULES).detect do |specific_rule| begin # if the rule is not expired if !expired?(specific_rule) # if the arguments received and the ones from the rule match, that means that we need to disable the current job specific_rule.match?(job_args) else # we remove the rule if it's expired remove_specific_rule(specific_rule) false end rescue StandardError => e Resque.logger.error "Failed to parse AllowDisableJob rules for #{job_name}: #{specific_rule.serialized_arguments}. Error: #{e.message}" false end end end
remove_specific_rule(rule)
click to toggle source
To remove a job we need to delete its counter, the entry from the rules hash and if the job has no more rules, we can remove the job's entry in the main set
# File lib/resque/plugins/disable_job/job.rb, line 84 def self.remove_specific_rule(rule) Resque.redis.del(rule.rule_key) Resque.redis.hdel(rule.all_rules_key, rule.digest) if Resque.redis.hlen(rule.all_rules_key).zero? Resque.redis.srem(rule.main_set, rule.job_name) end end
Private Class Methods
get_all_rules(job_name)
click to toggle source
# File lib/resque/plugins/disable_job/job.rb, line 100 def self.get_all_rules(job_name) Resque.redis.hgetall(Rule.new(job_name).all_rules_key).map do |digest, set_args| get_specific_rule(job_name, set_args, digest) end end
get_specific_rule(job_name, set_args, digest)
click to toggle source
Support functions for disabled?
# File lib/resque/plugins/disable_job/job.rb, line 94 def self.get_specific_rule(job_name, set_args, digest) rule = Rule.new(job_name, set_args) Resque.logger.error 'The DIGEST does not match' if rule.digest != digest rule end
record_matched_rule(job_name, job_args, rule)
click to toggle source
# File lib/resque/plugins/disable_job/job.rb, line 106 def self.record_matched_rule(job_name, job_args, rule) Resque.redis.incr rule.rule_key Resque.logger.info "Matched running job #{job_name}(#{job_args}) because it was disabled by #{rule}" end