Skip to content
This repository
Browse code

Use RPOPLPUSH to walk the queue in #queued. This will not have memory…

… issues when dealing with a large queue.
  • Loading branch information...
commit d569f96a8164440f4f4a97e0e3c465d32db38c7e 1 parent f89f205
Jonathan Julian authored April 01, 2013

Showing 1 changed file with 11 additions and 8 deletions. Show diff stats Hide diff stats

  1. 19  lib/resque/job.rb
19  lib/resque/job.rb
@@ -120,21 +120,24 @@ def self.destroy(queue, klass, *args)
120 120
     # Whereas specifying args will only find the 2nd job:
121 121
     #
122 122
     #   Resque::Job.queued(queue, 'UpdateGraph', 'mojombo')
123  
-    #
124  
-    # This method can be potentially very slow and memory intensive,
125  
-    # depending on the size of your queue, as it loads all jobs into
126  
-    # a Ruby array.
127 123
     def self.queued(queue, klass, *args)
128 124
       klass = klass.to_s
  125
+      tmp_queue = "queue:#{queue}:tmp:#{Time.now.to_i}"
  126
+      requeue_queue = "#{tmp_queue}:requeue"
  127
+      jobs = []
129 128
 
130  
-      redis.lrange("queue:#{queue}", 0, -1).inject([]) do |memo, string|
  129
+      while string = redis.rpoplpush("queue:#{queue}", tmp_queue)
131 130
         decoded = decode(string)
132 131
         if decoded['class'] == klass && (args.empty? || decoded['args'] == args)
133  
-          memo << new(queue, decoded)
  132
+          jobs.unshift new(queue, decoded)
134 133
         end
135  
-
136  
-        memo
  134
+        redis.rpoplpush(tmp_queue, requeue_queue)
137 135
       end
  136
+      loop do
  137
+        redis.rpoplpush(requeue_queue, "queue:#{queue}") or break
  138
+      end
  139
+
  140
+      jobs
138 141
     end
139 142
 
140 143
     # Given a string queue name, returns an instance of Resque::Job

0 notes on commit d569f96

Please sign in to comment.
Something went wrong with that request. Please try again.