Class: Resque::Plugins::DisableJob::Job

Inherits:
Object
  • Object
show all
Defined in:
lib/resque/plugins/disable_job/job.rb

Overview

The Job class contains the logic that determines if the current job is disabled, and methods to disable and enable a specific job.

Class Method Summary collapse

Class Method Details

.disable_job(name, specific_args: {}, timeout: DEFAULT_TIMEOUT) ⇒ Object

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



54
55
56
57
58
59
60
61
62
# File 'lib/resque/plugins/disable_job/job.rb', line 54

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) ⇒ Boolean

disabled? checks if the job and it’s arguments is disabled

Returns:

  • (Boolean)


12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 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_jobsObject



77
78
79
# File 'lib/resque/plugins/disable_job/job.rb', line 77

def self.disabled_jobs
  Resque.redis.smembers(Rule::JOBS_SET)
end

.enable_all(job_name) ⇒ Object



69
70
71
# File 'lib/resque/plugins/disable_job/job.rb', line 69

def self.enable_all(job_name)
  get_all_rules(job_name).map { |r| remove_specific_rule(r) }
end

.enable_all!Object



73
74
75
# File 'lib/resque/plugins/disable_job/job.rb', line 73

def self.enable_all!
  disabled_jobs.map { |job_name| enable_all(job_name) }
end

.enable_job(name, specific_args: {}) ⇒ Object

To enable a job, we just need to remove it



65
66
67
# File 'lib/resque/plugins/disable_job/job.rb', line 65

def self.enable_job(name, specific_args: {})
  remove_specific_rule(Rule.new(name, specific_args))
end

.expired?(rule) ⇒ Boolean

The rule is expired if the TTL of the rule key is -1.

Returns:

  • (Boolean)


46
47
48
# File 'lib/resque/plugins/disable_job/job.rb', line 46

def self.expired?(rule)
  Resque.redis.ttl(rule.rule_key) < 0
end

.match_rules(job_name, job_args, rules) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 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|
    # 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}" # rubocop:disable Layout/LineLength
    false
  end
end

.remove_specific_rule(rule) ⇒ Object

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



83
84
85
86
87
88
89
# File 'lib/resque/plugins/disable_job/job.rb', line 83

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