Class: Resque::Plugins::ResqueCleaner

Inherits:
Object
  • Object
show all
Defined in:
lib/resque_cleaner.rb

Overview

ResqueCleaner class provides useful functionalities to retry or clean failed jobs. Let’s clean up your failed list!

Defined Under Namespace

Modules: FailedJobEx Classes: Limiter

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeResqueCleaner

Initializes instance



22
23
24
25
26
# File 'lib/resque_cleaner.rb', line 22

def initialize
  @failure = Resque::Failure.backend
  @print_message = true
  @limiter = Limiter.new self
end

Instance Attribute Details

#limiterObject (readonly)

ResqueCleaner fetches all elements from Redis and checks them by linear when filtering them. Since there is a performance concern, ResqueCleaner handles only the latest x(default 1000) jobs.

You can change the value through limiter attribute. e.g. cleaner.limiter.maximum = 5000



16
17
18
# File 'lib/resque_cleaner.rb', line 16

def limiter
  @limiter
end

Set false if you don’t show any message.



19
20
21
# File 'lib/resque_cleaner.rb', line 19

def print_message
  @print_message
end

Instance Method Details

#clear(&block) ⇒ Object

Clears every jobs for which block evaluates to true.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/resque_cleaner.rb', line 99

def clear(&block)
  cleared = 0
  @limiter.lock do
    @limiter.jobs.each_with_index do |job,i|
      if !block_given? || block.call(job)
        index = @limiter.start_index + i - cleared
        # fetches again since you can't ensure that it is always true:
        # a == endode(decode(a))
        value = redis.lindex(:failed, index)
        redis.lrem(:failed, 1, value)
        cleared += 1
      end
    end
  end
  cleared
end

#clear_staleObject

Clears all jobs except the last X jobs



148
149
150
151
152
153
# File 'lib/resque_cleaner.rb', line 148

def clear_stale
  return 0 unless @limiter.on?
  c = @limiter.maximum
  redis.ltrim(:failed, -c, -1)
  c
end

#failureObject

Returns failure backend. Only supports redis backend.



34
35
36
# File 'lib/resque_cleaner.rb', line 34

def failure
  @failure
end

#log(msg) ⇒ Object

Outputs message. Overrides this method when you want to change a output stream.



293
294
295
# File 'lib/resque_cleaner.rb', line 293

def log(msg)
  puts msg if print?
end

#print?Boolean

Returns:

  • (Boolean)


297
298
299
# File 'lib/resque_cleaner.rb', line 297

def print?
  @print_message
end

Print stats



77
78
79
80
81
82
83
# File 'lib/resque_cleaner.rb', line 77

def print_stats(stats)
  log too_many_message if @limiter.on?
  stats.keys.sort.each do |k|
    log "%15s: %4d" % [k,stats[k]]
  end
  log "%15s: %4d" % ["total", @limiter.count]
end

#redisObject

Returns redis instance.



29
30
31
# File 'lib/resque_cleaner.rb', line 29

def redis
  Resque.redis
end

#requeue(clear_after_requeue = false, options = {}, &block) ⇒ Object

Retries every jobs for which block evaluates to true.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/resque_cleaner.rb', line 117

def requeue(clear_after_requeue=false, options={}, &block)
  requeued = 0
  queue = options["queue"] || options[:queue]
  @limiter.lock do
    @limiter.jobs.each_with_index do |job,i|
      if !block_given? || block.call(job)
        index = @limiter.start_index + i - requeued

        value = redis.lindex(:failed, index)
        redis.multi do
          Job.create(queue||job['queue'], job['payload']['class'], *job['payload']['args'])

          if clear_after_requeue
            # remove job
            # TODO: should use ltrim. not sure why i used lrem here...
            redis.lrem(:failed, 1, value)
          else
            # mark retried
            job['retried_at'] = Time.now.strftime("%Y/%m/%d %H:%M:%S")
            redis.lset(:failed, @limiter.start_index+i, Resque.encode(job))
          end
        end

        requeued += 1
      end
    end
  end
  requeued
end

#select(&block) ⇒ Object Also known as: failure_jobs

Returns every jobs for which block evaluates to true.



86
87
88
89
# File 'lib/resque_cleaner.rb', line 86

def select(&block)
  jobs = @limiter.jobs
  block_given? ? @limiter.jobs.select(&block) : jobs
end

#select_by_regex(regex) ⇒ Object



92
93
94
95
96
# File 'lib/resque_cleaner.rb', line 92

def select_by_regex(regex)
  select do |job|
    job.to_s =~ regex
  end
end

#stats_by_class(&block) ⇒ Object

Stats by class.



52
53
54
55
56
57
58
59
60
61
# File 'lib/resque_cleaner.rb', line 52

def stats_by_class(&block)
  jobs, stats = select(&block), {}
  jobs.each do |job|
    stats[job.klass_name] ||= 0
    stats[job.klass_name] += 1
  end

  print_stats(stats) if print?
  stats
end

#stats_by_date(&block) ⇒ Object

Stats by date.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/resque_cleaner.rb', line 39

def stats_by_date(&block)
  jobs, stats = select(&block), {}
  jobs.each do |job|
    date = job["failed_at"][0,10]
    stats[date] ||= 0
    stats[date] += 1
  end

  print_stats(stats) if print?
  stats
end

#stats_by_exception(&block) ⇒ Object

Stats by exception.



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/resque_cleaner.rb', line 64

def stats_by_exception(&block)
  jobs, stats = select(&block), {}
  jobs.each do |job|
    exception = job["exception"]
    stats[exception] ||= 0
    stats[exception] += 1
  end

  print_stats(stats) if print?
  stats
end

#too_many_messageObject



301
302
303
# File 'lib/resque_cleaner.rb', line 301

def too_many_message
  "There are too many failed jobs(count=#{@failure.count}). This only looks at last #{@limiter.maximum} jobs."
end