From 17d248c50fcfb55b6f3790a0ead30951ca93d550 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 26 Jul 2010 10:29:37 -0700 Subject: [PATCH 01/59] Depend on json_pure for JRuby compat --- resque.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resque.gemspec b/resque.gemspec index 503cbbd20..a6afda31e 100644 --- a/resque.gemspec +++ b/resque.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency "redis-namespace", "~> 0.7.0" s.add_dependency "vegas", "~> 0.1.2" s.add_dependency "sinatra", ">= 0.9.2" - s.add_dependency "json", ">= 1.1.0" + s.add_dependency "json_pure", "~> 1.4.0" s.description = < Date: Mon, 26 Jul 2010 10:29:46 -0700 Subject: [PATCH 02/59] Upgrade redis-namespace dependency --- resque.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resque.gemspec b/resque.gemspec index a6afda31e..9bac6225e 100644 --- a/resque.gemspec +++ b/resque.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.extra_rdoc_files = [ "LICENSE", "README.markdown" ] s.rdoc_options = ["--charset=UTF-8"] - s.add_dependency "redis-namespace", "~> 0.7.0" + s.add_dependency "redis-namespace", "~> 0.8.0" s.add_dependency "vegas", "~> 0.1.2" s.add_dependency "sinatra", ">= 0.9.2" s.add_dependency "json_pure", "~> 1.4.0" From f144aada3cd2d7bb3d7962e9f84188503bb6da0d Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 26 Jul 2010 10:30:45 -0700 Subject: [PATCH 03/59] v1.9.9 --- HISTORY.md | 6 ++++++ lib/resque/version.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 17e57a6eb..d6ac701c2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +## 1.9.9 (2010-07-26) + +* Depend on redis-namespace 0.8.0 +* Depend on json_pure instead of json (for JRuby compat) +* Bugfix: rails_env display in stats view + ## 1.9.8 (2010-07-20) * Bugfix: Worker.all should never return nil diff --git a/lib/resque/version.rb b/lib/resque/version.rb index db6158a05..379f81e4f 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.9.8' + Version = VERSION = '1.9.9' end From 3139fac9c7e0bc7be98850bf12b3034b3054e2ee Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Fri, 6 Aug 2010 17:52:41 -0700 Subject: [PATCH 04/59] Bugfix: before_fork should get passed the job --- lib/resque/worker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque/worker.rb b/lib/resque/worker.rb index 6f072aa21..f7ca0a517 100644 --- a/lib/resque/worker.rb +++ b/lib/resque/worker.rb @@ -112,7 +112,7 @@ def work(interval = 5, &block) if not @paused and job = reserve log "got: #{job.inspect}" - run_hook :before_fork + run_hook :before_fork, job working_on job if @child = fork From d83b7b3b356a8c59849394a2cec55080bb37bb3b Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Fri, 6 Aug 2010 17:53:42 -0700 Subject: [PATCH 05/59] v1.9.10 --- HISTORY.md | 4 ++++ lib/resque/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index d6ac701c2..993ad332d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,7 @@ +## 1.9.10 (2010-08-06) + +* Bugfix: before_fork should get passed the job + ## 1.9.9 (2010-07-26) * Depend on redis-namespace 0.8.0 diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 379f81e4f..ab6c5c0af 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.9.9' + Version = VERSION = '1.9.10' end From d75e0d6f07b0a2b9cfd41757d9575c04222f8262 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Sun, 8 Aug 2010 23:38:10 -0700 Subject: [PATCH 06/59] Optional leftright support --- test/test_helper.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test_helper.rb b/test/test_helper.rb index 25274b45b..71474c6b6 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -5,6 +5,11 @@ require 'rubygems' require 'resque' +begin + require 'leftright' +rescue LoadError +end + # # make sure we can run redis From 8f5ff340b2cc708f1487aed20db5e64df1e4d5fe Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Sun, 8 Aug 2010 23:40:10 -0700 Subject: [PATCH 07/59] Support redis:// format. Closes #133 --- lib/resque.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index ec740cc21..8b6b161cf 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -30,9 +30,14 @@ module Resque # or `Redis::Namespace`. def redis=(server) if server.respond_to? :split - host, port, db = server.split(':') - redis = Redis.new(:host => host, :port => port, - :thread_safe => true, :db => db) + if server =~ /redis\:\/\// + redis = Redis.connect(:url => server) + else + host, port, db = server.split(':') + redis = Redis.new(:host => host, :port => port, + :thread_safe => true, :db => db) + end + @redis = Redis::Namespace.new(:resque, :redis => redis) elsif server.respond_to? :namespace= @redis = server From 3840c790c41a9a95096f71128697100d4e7dfb09 Mon Sep 17 00:00:00 2001 From: "nicholas a. evans" Date: Fri, 30 Jul 2010 03:11:26 +0800 Subject: [PATCH 08/59] make shutdown? method, which plugins can override --- lib/resque/worker.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/resque/worker.rb b/lib/resque/worker.rb index f7ca0a517..5a879710c 100644 --- a/lib/resque/worker.rb +++ b/lib/resque/worker.rb @@ -108,7 +108,7 @@ def work(interval = 5, &block) startup loop do - break if @shutdown + break if shutdown? if not @paused and job = reserve log "got: #{job.inspect}" @@ -265,6 +265,11 @@ def shutdown! kill_child end + # Should this worker shutdown as soon as current job is finished? + def shutdown? + @shutdown + end + # Kills the forked child immediately, without remorse. The job it # is processing will not be completed. def kill_child From c70d4546aafba5ab9edbae4d44c81ff3b8c4ea8a Mon Sep 17 00:00:00 2001 From: Chris Lerum Date: Wed, 18 Aug 2010 10:33:12 -0400 Subject: [PATCH 09/59] Fix grammar in README --- README.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 1c823130b..d966aa580 100644 --- a/README.markdown +++ b/README.markdown @@ -9,8 +9,8 @@ Background jobs can be any Ruby class or module that responds to jobs or you can create new classes specifically to do work. Or, you can do both. -Resque is heavily inspired by DelayedJob (which rocks) and is -comprised of three parts: +Resque is heavily inspired by DelayedJob (which rocks) and comprises +three parts: 1. A Ruby library for creating, querying, and processing jobs 2. A Rake task for starting a worker which processes jobs From 28e3f03d6536fb70254668e7e05c5971676c1a34 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 17 Aug 2010 12:53:14 +0800 Subject: [PATCH 10/59] Switch from the json_pure gem to the json gem, which is now cross-platform at least across MRI/YARV, JRuby, and Rubinius. Require 1.4.6 as a minimum, since that's known working on all of these platforms --- resque.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resque.gemspec b/resque.gemspec index 9bac6225e..4a11e10ff 100644 --- a/resque.gemspec +++ b/resque.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency "redis-namespace", "~> 0.8.0" s.add_dependency "vegas", "~> 0.1.2" s.add_dependency "sinatra", ">= 0.9.2" - s.add_dependency "json_pure", "~> 1.4.0" + s.add_dependency "json", "~> 1.4.6" s.description = < Date: Tue, 10 Aug 2010 23:37:53 +0800 Subject: [PATCH 11/59] Allow the Redis namespace to be set via "host:port/namespace" --- lib/resque.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index 8b6b161cf..8f94d88fe 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -26,19 +26,24 @@ module Resque # Accepts: # 1. A 'hostname:port' string # 2. A 'hostname:port:db' string (to select the Redis db) - # 3. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`, + # 3. A 'hostname:port/namespace' string (to set the Redis namespace) + # 4. A redis URL string 'redis://host:port' + # 5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`, # or `Redis::Namespace`. def redis=(server) if server.respond_to? :split + namespace = :resque + if server =~ /redis\:\/\// redis = Redis.connect(:url => server) else + server, namespace = server.split('/', 2) host, port, db = server.split(':') redis = Redis.new(:host => host, :port => port, :thread_safe => true, :db => db) end - @redis = Redis::Namespace.new(:resque, :redis => redis) + @redis = Redis::Namespace.new(namespace, :redis => redis) elsif server.respond_to? :namespace= @redis = server else From f15aedb075103cf4750134dee7019757bf4c7136 Mon Sep 17 00:00:00 2001 From: Aaron Quint Date: Mon, 23 Aug 2010 14:00:47 +0800 Subject: [PATCH 12/59] Tests for setting the resque-namespace through the url-string --- lib/resque.rb | 3 +-- test/resque_test.rb | 9 ++++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index 8f94d88fe..fbdc23e40 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -32,8 +32,6 @@ module Resque # or `Redis::Namespace`. def redis=(server) if server.respond_to? :split - namespace = :resque - if server =~ /redis\:\/\// redis = Redis.connect(:url => server) else @@ -42,6 +40,7 @@ def redis=(server) redis = Redis.new(:host => host, :port => port, :thread_safe => true, :db => db) end + namespace ||= :resque @redis = Redis::Namespace.new(namespace, :redis => redis) elsif server.respond_to? :namespace= diff --git a/test/resque_test.rb b/test/resque_test.rb index 919423c91..8d4c4a81c 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -8,6 +8,13 @@ Resque.push(:people, { 'name' => 'bob' }) Resque.push(:people, { 'name' => 'mark' }) end + + test "can set a namespace through a url-like string" do + assert Resque.redis + assert_equal :resque, Resque.redis.namespace + Resque.redis = 'localhost:9736/namespace' + assert_equal 'namespace', Resque.redis.namespace + end test "can put jobs on a queue" do assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp') @@ -222,4 +229,4 @@ test "decode bad json" do assert_nil Resque.decode("{\"error\":\"Module not found \\u002\"}") end -end +end \ No newline at end of file From 3d9814dfa9b36adf8238a0f090901e3cd074773c Mon Sep 17 00:00:00 2001 From: Adam Cooke Date: Thu, 19 Aug 2010 14:04:05 +0100 Subject: [PATCH 13/59] fix working page in web interface so counts are displayed correctly --- lib/resque/server/views/working.erb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/resque/server/views/working.erb b/lib/resque/server/views/working.erb index ae88ccc34..db2b4ae0d 100644 --- a/lib/resque/server/views/working.erb +++ b/lib/resque/server/views/working.erb @@ -27,7 +27,7 @@ <% else %> - <% workers = resque.working %> + <% workers = resque.working.reject { |w| w.idle? } %>

<%= workers.size %> of <%= resque.workers.size %> Workers Working

The list below contains all workers which are currently running a job.

@@ -45,7 +45,6 @@ <% for worker in workers.sort_by { |w| w.job['run_at'] ? w.job['run_at'] : '' } %> <% job = worker.job %> - <% next if worker.idle? %> From 193289ba94c3c6b31eee8a5beff89b7ceb5734db Mon Sep 17 00:00:00 2001 From: Daniel Huckstep Date: Fri, 30 Jul 2010 10:55:30 +0800 Subject: [PATCH 14/59] after_enqueue hook --- lib/resque/job.rb | 6 +++++- lib/resque/plugin.rb | 5 +++++ test/job_hooks_test.rb | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/resque/job.rb b/lib/resque/job.rb index 59eb561fb..4e463bfe1 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -48,7 +48,11 @@ def self.create(queue, klass, *args) raise NoClassError.new("Jobs must be given a class.") end - Resque.push(queue, :class => klass.to_s, :args => args) + ret = Resque.push(queue, :class => klass.to_s, :args => args) + Plugin.after_enqueue_hooks(klass).each do |hook| + klass.send(hook, *args) + end + ret end # Removes a job from a queue. Expects a string queue name, a diff --git a/lib/resque/plugin.rb b/lib/resque/plugin.rb index a19b6fed6..3152dd4bc 100644 --- a/lib/resque/plugin.rb +++ b/lib/resque/plugin.rb @@ -42,5 +42,10 @@ def after_hooks(job) def failure_hooks(job) job.methods.grep(/^on_failure/).sort end + + # Given an object, returns a list `after_enqueue` hook names. + def after_enqueue_hooks(job) + job.methods.grep(/^after_enqueue/).sort + end end end diff --git a/test/job_hooks_test.rb b/test/job_hooks_test.rb index e4368bf30..e72cc6664 100644 --- a/test/job_hooks_test.rb +++ b/test/job_hooks_test.rb @@ -228,6 +228,27 @@ def self.on_failure_record_failure(exception, history) end end +context "Resque::Job after_enqueue" do + include PerformJob + + class ::AfterEnqueueJob + def self.after_enqueue_record_history(history) + history << :after_enqueue + end + + def self.perform(history) + end + end + + test "the after enqueue hook should run" do + history = [] + @worker = Resque::Worker.new(:jobs) + Resque::Job.create(:jobs, AfterEnqueueJob, history) + @worker.work(0) + assert_equal history, [:after_enqueue], "after_enqueue was not run" + end +end + context "Resque::Job all hooks" do include PerformJob From 61d9cb5bfb75391cd67983e9b611ea02bfdcd641 Mon Sep 17 00:00:00 2001 From: Daniel Huckstep Date: Tue, 10 Aug 2010 00:40:14 +0800 Subject: [PATCH 15/59] Add docs for after_enqueue hook --- docs/HOOKS.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/HOOKS.md b/docs/HOOKS.md index 1c942d479..c091a60e3 100644 --- a/docs/HOOKS.md +++ b/docs/HOOKS.md @@ -66,6 +66,9 @@ An unnamed hook (`before_perform`) will be executed first. The available hooks are: +* `after_enqueue`: Called with the job args after a job is placed on the queue. + Any exception raised propagates up to the code which queued the job. + * `before_perform`: Called with the job args before perform. If it raises `Resque::Job::DontPerform`, the job is aborted. If other exceptions are raised, they will be propagated up the the `Resque::Failure` @@ -99,6 +102,13 @@ look something like this. Modules are even better because jobs can use many of them. + module ScaledJob + def after_enqueue_scale_workers(*args) + Logger.info "Scaling worker count up" + Scaler.up! if Redis.info[:pending].to_i > 25 + end + end + module LoggedJob def before_perform_log_job(*args) Logger.info "About to perform #{self} with #{args.inspect}" @@ -115,6 +125,7 @@ Modules are even better because jobs can use many of them. class MyJob extend LoggedJob extend RetriedJob + extend ScaledJob def self.perform(*args) ... end From 3c7bd9e3a4396f53994ec9ae5315308a4bf8bb2a Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 23 Aug 2010 19:00:18 -0700 Subject: [PATCH 16/59] v1.10.0 --- HISTORY.md | 9 +++++++++ lib/resque/version.rb | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 993ad332d..910d07eeb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,12 @@ +## 1.10.0 (2010-08-23) + +* Support redis:// string format in `Resque.redis=` +* Using new cross-platform JSON gem. +* Added `after_enqueue` plugin hook. +* Added `shutdown?` method which can be overridden. +* Added support for the "leftright" gem when running tests. +* Grammarfix: In the README + ## 1.9.10 (2010-08-06) * Bugfix: before_fork should get passed the job diff --git a/lib/resque/version.rb b/lib/resque/version.rb index ab6c5c0af..7f5b32233 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.9.10' + Version = VERSION = '1.10.0' end From 76f0597391aec56a77f8bfb32a500ba07ae5b073 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 23 Aug 2010 19:42:46 -0700 Subject: [PATCH 17/59] Web UI: Group /workers page by hostnames --- lib/resque/server.rb | 15 +++++++++++ lib/resque/server/views/workers.erb | 39 ++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/resque/server.rb b/lib/resque/server.rb index 066401ccb..b3443fe0f 100644 --- a/lib/resque/server.rb +++ b/lib/resque/server.rb @@ -80,6 +80,21 @@ def show_args(args) Array(args).map { |a| a.inspect }.join("\n") end + def worker_hosts + @worker_hosts ||= worker_hosts! + end + + def worker_hosts! + hosts = Hash.new { [] } + + Resque.workers.each do |worker| + host, _ = worker.to_s.split(':') + hosts[host] += [worker.to_s] + end + + hosts + end + def partial? @partial end diff --git a/lib/resque/server/views/workers.erb b/lib/resque/server/views/workers.erb index 3fd6fccb6..3dd7f0a56 100644 --- a/lib/resque/server/views/workers.erb +++ b/lib/resque/server/views/workers.erb @@ -1,3 +1,5 @@ +<% @subtabs = worker_hosts.keys.sort unless worker_hosts.size == 1 %> + <% if params[:id] && worker = Resque::Worker.find(params[:id]) %>

Worker <%= worker %>

@@ -34,13 +36,19 @@
<%= state %>
-<% elsif params[:id] %> +<% elsif params[:id] && !worker_hosts.keys.include?(params[:id]) && params[:id] != 'all' %>

Worker doesn't exist

-<% else %> +<% elsif worker_hosts.size == 1 || params[:id] %> -

<%= resque.workers.size %> Workers

+ <% if worker_hosts.size == 1 || params[:id] == 'all' %> + <% workers = Resque.workers %> + <% else %> + <% workers = worker_hosts[params[:id]].map { |id| Resque::Worker.find(id) } %> + <% end %> + +

<%= workers.size %> Workers

The workers listed below are all registered as active on your system.

@@ -49,7 +57,7 @@ - <% for worker in (workers = resque.workers.sort_by { |w| w.to_s }) %> + <% for worker in (workers = workers.sort_by { |w| w.to_s }) %> @@ -75,4 +83,27 @@ <% end %>
Queues Processing
<%= state %>
<%=poll%> + +<% else %> + +

Workers

+

The hostnames below all have registered workers. Select a hostname to view its workers, or "all" to see all workers.

+ + + + + + <% for hostname, workers in worker_hosts %> + + + + + <% end %> + + + + +
HostnameWorkers
"><%= hostname %><%= workers.size %>
">all workers<%= Resque.workers.size %>
+ + <% end %> From aba6f6f52560cce9c1bb842786db10903814ca25 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 23 Aug 2010 19:43:32 -0700 Subject: [PATCH 18/59] v1.11.0 --- HISTORY.md | 4 ++++ lib/resque/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 910d07eeb..15fbfa541 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,7 @@ +## 1.11.0 (2010-08-23) + +* Web UI: Group /workers page by hostnames + ## 1.10.0 (2010-08-23) * Support redis:// string format in `Resque.redis=` diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 7f5b32233..7c5357662 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.10.0' + Version = VERSION = '1.11.0' end From 1852cea9c8eb0d6428c341284a6a14a0cc4a571e Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 23 Aug 2010 20:06:42 -0700 Subject: [PATCH 19/59] Web UI: Sort workers, don't always show subtabs --- lib/resque/server/views/queues.erb | 2 +- lib/resque/server/views/workers.erb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/resque/server/views/queues.erb b/lib/resque/server/views/queues.erb index 693a5ef1e..8025561cf 100644 --- a/lib/resque/server/views/queues.erb +++ b/lib/resque/server/views/queues.erb @@ -1,4 +1,4 @@ -<% @subtabs = resque.queues unless partial? %> +<% @subtabs = resque.queues unless partial? || params[:id].nil? %> <% if queue = params[:id] %> diff --git a/lib/resque/server/views/workers.erb b/lib/resque/server/views/workers.erb index 3dd7f0a56..0ddb01640 100644 --- a/lib/resque/server/views/workers.erb +++ b/lib/resque/server/views/workers.erb @@ -85,7 +85,7 @@ <%=poll%> <% else %> - + <% @subtabs = [] %>

Workers

The hostnames below all have registered workers. Select a hostname to view its workers, or "all" to see all workers.

@@ -93,7 +93,7 @@ - <% for hostname, workers in worker_hosts %> + <% for hostname, workers in worker_hosts.sort_by { |h,w| h } %> From 37385f18bc634f86710bb93ee42d04c8c52ab3d0 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Thu, 2 Sep 2010 17:54:18 -0700 Subject: [PATCH 20/59] new archive url --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index d966aa580..1ade9a768 100644 --- a/README.markdown +++ b/README.markdown @@ -764,7 +764,7 @@ To join the list simply send an email to . This will subscribe you and send you information about your subscription, including unsubscribe information. -The archive can be found at . +The archive can be found at . Meta From db3bdf658ad1aaf8bb8e074e9f5cebd32f759dbb Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Mon, 27 Sep 2010 11:23:21 -0400 Subject: [PATCH 21/59] add uniqueness test for later --- test/resque_test.rb | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/test/resque_test.rb b/test/resque_test.rb index 8d4c4a81c..3cba3d8d1 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -229,4 +229,53 @@ test "decode bad json" do assert_nil Resque.decode("{\"error\":\"Module not found \\u002\"}") end -end \ No newline at end of file +=begin + class UniqueJob + @queue = :unique + @unique_jobs = true + end + + class NonUnique + @queue = :unique + end + + class OtherUnique + @queue = :unique2 + @unique_jobs = true + end + + test "unique jobs are unique" do + #does uniqueness work? + Resque.enqueue(UniqueJob, {:_id => 'my_id', :arg1=> 'my args1'}) + assert_equal(1, Resque.size(:unique)) + assert_equal('my args1', Resque.peek(:unique)['args'][0]['arg1']) + assert_equal('my_id', Resque.peek(:unique)['args'][0]['_id']) + Resque.enqueue(UniqueJob, {:_id => 'my_id', :arg1=> 'my args2'}) + assert_equal(1, Resque.size(:unique)) + assert_equal('my args2', Resque.peek(:unique)['args'][0]['arg1']) + + #if I enqueue unique jobs with the same key in 2 queues, do I get 2 jobs? + puts 'here we go' + Resque.enqueue(UniqueJob, {:_id => 'my_id3', :arg1=> 'my arg3'}) + assert_equal(2, Resque.size(:unique)) + Resque.enqueue(OtherUnique, {:_id => 'my_id3', :arg1=> 'my args4'}) + #following line fails because :unique and :unique2 are in the same collection + #\assert_equal(2, Resque.size(:unique)) + assert_equal(1, Resque.size(:unique2)) + + #can I enqueue normal jobs in the unique queue? + Resque.enqueue(NonUnique, {:arg1=> 'my args'}) + assert_equal(3, Resque.size(:unique)) + Resque.enqueue(NonUnique, {:_id => 'my_id', :_id => 'my_id', :arg1=> 'my args2'}) + assert_equal(4, Resque.size(:unique)) + + #how do unique jobs work without a given _id? + Resque.enqueue(UniqueJob, {:arg1=> 'my args3'}) + assert_equal(5, Resque.size(:unique)) + assert_equal('my args3', Resque.peek(:unique, 4)['args'][0]['arg1']) + Resque.enqueue(UniqueJob, {:arg1=> 'my args4'}) + assert_equal(6, Resque.size(:unique)) + assert_equal('my args4', Resque.peek(:unique, 5)['args'][0]['arg1']) + end +=end +end From 9fbe0d99700343e19b416cd66b32c8bb018d70ac Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 28 Sep 2010 14:33:44 -0400 Subject: [PATCH 22/59] fork resque to use mongo instead of redis --- Rakefile | 4 +- bin/resque-web | 6 +- lib/resque.rb | 132 ++++++++++++------------ lib/resque/failure/redis.rb | 12 +-- lib/resque/helpers.rb | 12 ++- lib/resque/job.rb | 19 +--- lib/resque/server/views/layout.erb | 12 +-- lib/resque/server/views/stats.erb | 17 ++- lib/resque/stat.rb | 9 +- lib/resque/worker.rb | 55 +++++----- tasks/redis.rake | 159 ----------------------------- test/redis-test.conf | 115 --------------------- test/resque_test.rb | 74 +++++++------- test/test_helper.rb | 97 ++++++++++++------ test/worker_test.rb | 8 +- 15 files changed, 239 insertions(+), 492 deletions(-) delete mode 100644 tasks/redis.rake delete mode 100644 test/redis-test.conf diff --git a/Rakefile b/Rakefile index 1d4f22433..faa09d68e 100644 --- a/Rakefile +++ b/Rakefile @@ -1,8 +1,6 @@ # # Setup # - -load 'tasks/redis.rake' require 'rake/testtask' $LOAD_PATH.unshift 'lib' @@ -40,7 +38,7 @@ end # Install # -task :install => [ 'redis:install', 'dtach:install' ] +task :install => [ 'dtach:install' ] # diff --git a/bin/resque-web b/bin/resque-web index c2b8832e6..737f22679 100755 --- a/bin/resque-web +++ b/bin/resque-web @@ -16,8 +16,8 @@ Vegas::Runner.new(Resque::Server, 'resque-web', { load path.to_s.strip if path } }) do |runner, opts, app| - opts.on('-N NAMESPACE', "--namespace NAMESPACE", "set the Redis namespace") {|namespace| - runner.logger.info "Using Redis namespace '#{namespace}'" - Resque.redis.namespace = namespace + opts.on('-N NAMESPACE', "--namespace NAMESPACE", "set the Mongo database") {|namespace| + runner.logger.info "Using Mongo database '#{namespace}'" + Resque.mongo_db= namespace } end diff --git a/lib/resque.rb b/lib/resque.rb index fbdc23e40..fe812a266 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -1,4 +1,3 @@ -require 'redis/namespace' begin require 'yajl' @@ -6,6 +5,8 @@ require 'json' end +require 'mongo' + require 'resque/version' require 'resque/errors' @@ -23,48 +24,57 @@ module Resque include Helpers extend self - # Accepts: - # 1. A 'hostname:port' string - # 2. A 'hostname:port:db' string (to select the Redis db) - # 3. A 'hostname:port/namespace' string (to set the Redis namespace) - # 4. A redis URL string 'redis://host:port' - # 5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`, - # or `Redis::Namespace`. - def redis=(server) - if server.respond_to? :split - if server =~ /redis\:\/\// - redis = Redis.connect(:url => server) + def mongo=(server) + if server.is_a? String + opts = server.split(':') + host = opts[0] + if opts[1] =~ /\// + opts = opts[1].split('/') + port = opts[0] + queuedb = opts[1] else - server, namespace = server.split('/', 2) - host, port, db = server.split(':') - redis = Redis.new(:host => host, :port => port, - :thread_safe => true, :db => db) + port = opts[1] end - namespace ||= :resque - - @redis = Redis::Namespace.new(namespace, :redis => redis) - elsif server.respond_to? :namespace= - @redis = server - else - @redis = Redis::Namespace.new(:resque, :redis => server) + conn = Mongo::Connection.new host, port + elsif server.is_a? Hash + conn = Mongo::Connection.new(options[:server], options[:port], options) + queuedb = options[:queuedb] || 'resque' + elsif server.is_a? Mongo::Connection + conn = server end + queuedb ||= 'resque' + @mongo = conn.db queuedb + add_indexes end - # Returns the current Redis connection. If none has been created, will + # Returns the current Mongo connection. If none has been created, will # create a new one. - def redis - return @redis if @redis - self.redis = 'localhost:6379' - self.redis + def mongo + return @mongo if @mongo + self.mongo = 'localhost:27017/resque' + self.mongo end - def redis_id - # support 1.x versions of redis-rb - if redis.respond_to?(:server) - redis.server - else - redis.client.id - end + def mongo_db=(db) + @mongo.conn.db = db + end + + + def add_indexes + mongo_workers.create_index :worker + mongo_stats.create_index :stat + end + + def mongo_workers + mongo['resque.workers'] + end + + def mongo_stats + mongo['resque.stats'] + end + + def mongo_failures + mongo['resque.failures'] end # The `before_first_fork` hook will be run in the **parent** process @@ -115,7 +125,7 @@ def after_fork=(after_fork) end def to_s - "Resque Client connected to #{redis_id}" + "Resque Client connected to #{mongo.connection.host}:#{mongo.connection.port}/#{mongo.name}" end @@ -126,21 +136,23 @@ def to_s # Pushes a job onto a queue. Queue name should be a string and the # item should be any JSON-able Ruby object. def push(queue, item) - watch_queue(queue) - redis.rpush "queue:#{queue}", encode(item) + mongo[queue] << item end # Pops a job off a queue. Queue name should be a string. # # Returns a Ruby object. def pop(queue) - decode redis.lpop("queue:#{queue}") + mongo[queue].find_and_modify(:sort => [:natural, :desc], :remove => true ) + rescue Mongo::OperationFailure => e + return nil if e.message =~ /No matching object/ + raise e end # Returns an integer representing the size of a queue. # Queue name should be a string. def size(queue) - redis.llen("queue:#{queue}").to_i + mongo[queue].count end # Returns an array of items currently queued. Queue name should be @@ -152,39 +164,27 @@ def size(queue) # To get the 3rd page of a 30 item, paginatied list one would use: # Resque.peek('my_list', 59, 30) def peek(queue, start = 0, count = 1) - list_range("queue:#{queue}", start, count) + list_range(queue, start, count) end # Does the dirty work of fetching a range of items from a Redis list # and converting them into Ruby objects. def list_range(key, start = 0, count = 1) - if count == 1 - decode redis.lindex(key, start) - else - Array(redis.lrange(key, start, start+count-1)).map do |item| - decode item - end - end + items = mongo[key].find({ }, { :limit => count, :skip => start}).to_a.map{ |i| i} + count > 1 ? items : items.first end # Returns an array of all known Resque queues as strings. - def queues - Array(redis.smembers(:queues)) + def queues + names = mongo.collection_names + names.delete_if{ |name| name == 'system.indexes' || name =~ /resque\./ } end # Given a queue name, completely deletes the queue. def remove_queue(queue) - redis.srem(:queues, queue.to_s) - redis.del("queue:#{queue}") - end - - # Used internally to keep track of which queues we've created. - # Don't call this directly. - def watch_queue(queue) - redis.sadd(:queues, queue.to_s) + mongo[queue].drop end - # # job shortcuts # @@ -286,9 +286,9 @@ def info :processed => Stat[:processed], :queues => queues.size, :workers => workers.size.to_i, - :working => working.size, + :working => working.count, :failed => Stat[:failed], - :servers => [redis_id], + :servers => to_s, :environment => ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development' } end @@ -296,8 +296,12 @@ def info # Returns an array of all known Resque keys in Redis. Redis' KEYS operation # is O(N) for the keyspace, so be careful - this can be slow for big databases. def keys - redis.keys("*").map do |key| - key.sub("#{redis.namespace}:", '') - end + names = mongo.collection_names + #names.delete_if{ |name| name == 'system.indexes' || name =~ /resque\./ } + end + + def drop + mongo.collections.each{ |collection| collection.drop unless collection.name =~ /^system./ } + @mongo = nil end end diff --git a/lib/resque/failure/redis.rb b/lib/resque/failure/redis.rb index 1a91c5f46..b1dd5c77f 100644 --- a/lib/resque/failure/redis.rb +++ b/lib/resque/failure/redis.rb @@ -1,6 +1,6 @@ module Resque module Failure - # A Failure backend that stores exceptions in Redis. Very simple but + # A Failure backend that stores exceptions in Mongo. Very simple but # works out of the box, along with support in the Resque web app. class Redis < Base def save @@ -13,20 +13,20 @@ def save :worker => worker.to_s, :queue => queue } - data = Resque.encode(data) - Resque.redis.rpush(:failed, data) + Resque.mongo_failures << data end def self.count - Resque.redis.llen(:failed).to_i + Resque.mongo_failures.count end def self.all(start = 0, count = 1) - Resque.list_range(:failed, start, count) + all_failures = Resque.mongo_failures.find().sort([:natural, :desc]).skip(start).limit(count).to_a + all_failures.size == 1 ? all_failures.first : all_failures end def self.clear - Resque.redis.del(:failed) + Resque.mongo_failures.remove end def self.requeue(index) diff --git a/lib/resque/helpers.rb b/lib/resque/helpers.rb index 417d6b3b5..9c9a175ce 100644 --- a/lib/resque/helpers.rb +++ b/lib/resque/helpers.rb @@ -2,8 +2,16 @@ module Resque # Methods used by various classes in Resque. module Helpers # Direct access to the Redis instance. - def redis - Resque.redis + #def mongo + # Resque.mongo + #end + + def mongo_workers + Resque.mongo_workers + end + + def mongo_stats + Resque.mongo_stats end # Given a Ruby object, returns a string suitable for storage in a diff --git a/lib/resque/job.rb b/lib/resque/job.rb index 4e463bfe1..41ffed6da 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -80,20 +80,11 @@ def self.create(queue, klass, *args) # depending on the size of your queue, as it loads all jobs into # a Ruby array before processing. def self.destroy(queue, klass, *args) - klass = klass.to_s - queue = "queue:#{queue}" - destroyed = 0 - - if args.empty? - redis.lrange(queue, 0, -1).each do |string| - if decode(string)['class'] == klass - destroyed += redis.lrem(queue, 0, string).to_i - end - end - else - destroyed += redis.lrem(queue, 0, encode(:class => klass, :args => args)) - end - + collection = Resque.mongo[queue] + selector = {'class' => klass.to_s} + selector['args'] = args unless args.empty? + destroyed = collection.find(selector).count + collection.remove(selector, :safe => true) destroyed end diff --git a/lib/resque/server/views/layout.erb b/lib/resque/server/views/layout.erb index 7ae77b3f0..1262e6b79 100644 --- a/lib/resque/server/views/layout.erb +++ b/lib/resque/server/views/layout.erb @@ -16,11 +16,9 @@ <%= tab tab_name %> <% end %> - <% if Resque.redis.namespace != :resque %> - - <%= Resque.redis.namespace %> - - <% end %> + + <%= Resque.to_s %> + <% if @subtabs %> @@ -37,8 +35,8 @@ - \ No newline at end of file + diff --git a/lib/resque/server/views/stats.erb b/lib/resque/server/views/stats.erb index 98f5d2ce0..df3c945d0 100644 --- a/lib/resque/server/views/stats.erb +++ b/lib/resque/server/views/stats.erb @@ -1,4 +1,4 @@ -<% @subtabs = %w( resque redis keys ) %> +<% @subtabs = %w( resque mongo keys ) %> <% if params[:key] %> @@ -20,11 +20,11 @@ <% end %>
Hostname Workers
"><%= hostname %> <%= workers.size %>
-<% elsif params[:id] == 'redis' %> +<% elsif params[:id] == 'mongo' %> -

<%= resque.redis_id %>

+

<%= resque.to_s %>

- <% for key, value in resque.redis.info.to_a.sort_by { |i| i[0].to_s } %> + <% resque.mongo.stats.each_pair do |key, value| %>
<%= key %> @@ -38,12 +38,10 @@ <% elsif params[:id] == 'keys' %> -

Keys owned by <%= resque %>

-

(All keys are actually prefixed with "<%= Resque.redis.namespace %>:")

+

Collections in <%= resque.to_s %>

- - + <% for key in resque.keys.sort %> @@ -51,8 +49,7 @@ - - + <% end %>
keytypecollection size
"><%= key %> <%= resque.redis.type key %><%= redis_get_size key %><%= resque.mongo[key].count %>
diff --git a/lib/resque/stat.rb b/lib/resque/stat.rb index db286cc0b..dad0206fa 100644 --- a/lib/resque/stat.rb +++ b/lib/resque/stat.rb @@ -11,7 +11,8 @@ module Stat # Returns the int value of a stat, given a string stat name. def get(stat) - redis.get("stat:#{stat}").to_i + value = mongo_stats.find_one :stat => stat + value.nil? ? 0 : value['value'] end # Alias of `get` @@ -24,7 +25,7 @@ def [](stat) # Can optionally accept a second int parameter. The stat is then # incremented by that amount. def incr(stat, by = 1) - redis.incrby("stat:#{stat}", by) + mongo_stats.update({:stat => stat}, {'$inc' => {:value => by}}, :upsert => true) end # Increments a stat by one. @@ -37,7 +38,7 @@ def <<(stat) # Can optionally accept a second int parameter. The stat is then # decremented by that amount. def decr(stat, by = 1) - redis.decrby("stat:#{stat}", by) + mongo_stats.update({ :stat => stat}, { '$inc' => { :value => -by}}) end # Decrements a stat by one. @@ -47,7 +48,7 @@ def >>(stat) # Removes a stat from Redis, effectively setting it to 0. def clear(stat) - redis.del("stat:#{stat}") + mongo_stats.remove({:stat => stat}) end end end diff --git a/lib/resque/worker.rb b/lib/resque/worker.rb index 5a879710c..d6f75a116 100644 --- a/lib/resque/worker.rb +++ b/lib/resque/worker.rb @@ -24,18 +24,13 @@ class Worker # Returns an array of all worker objects. def self.all - Array(redis.smembers(:workers)).map { |id| find(id) }.compact + mongo_workers.distinct(:worker).map{|worker| find(worker)}.compact end # Returns an array of all worker objects currently processing # jobs. def self.working - names = all - return [] unless names.any? - names.map! { |name| "worker:#{name}" } - redis.mapped_mget(*names).keys.map do |key| - find key.sub("worker:", '') - end.compact + working = mongo_workers.find({ 'working_on' => { '$exists' => true}}).to_a.map{|w| find(w['worker'])} end # Returns a single worker object. Accepts a string id. @@ -58,7 +53,7 @@ def self.attach(worker_id) # Given a string worker id, return a boolean indicating whether the # worker exists def self.exists?(worker_id) - redis.sismember(:workers, worker_id) + mongo_workers.find({ :worker => worker_id.to_s}).count > 0 end # Workers should be initialized with an array of string queue @@ -298,15 +293,15 @@ def unpause_processing end # Looks for any workers which should be running on this server - # and, if they're not, removes them from Redis. + # and, if they're not, removes them from Mongo. # # This is a form of garbage collection. If a server is killed by a # hard shutdown, power failure, or something else beyond our # control, the Resque workers will not die gracefully and therefore - # will leave stale state information in Redis. + # will leave stale state information in Mongo. # - # By checking the current Redis state against the actual - # environment, we can determine if Redis is old and clean it up a bit. + # By checking the current Mongo state against the actual + # environment, we can determine if Mongo is old and clean it up a bit. def prune_dead_workers all_workers = Worker.all known_workers = worker_pids unless all_workers.empty? @@ -322,7 +317,7 @@ def prune_dead_workers # Registers ourself as a worker. Useful when entering the worker # lifecycle on startup. def register_worker - redis.sadd(:workers, self) + mongo_workers << { :worker => self.to_s} started! end @@ -348,30 +343,28 @@ def unregister_worker job.fail(DirtyExit.new) end - redis.srem(:workers, self) - redis.del("worker:#{self}") - redis.del("worker:#{self}:started") + mongo_workers.remove :worker => self.to_s Stat.clear("processed:#{self}") Stat.clear("failed:#{self}") end - # Given a job, tells Redis we're working on it. Useful for seeing + # Given a job, tells Mongo we're working on it. Useful for seeing # what workers are doing and when. def working_on(job) job.worker = self data = encode \ - :queue => job.queue, - :run_at => Time.now.to_s, - :payload => job.payload - redis.set("worker:#{self}", data) + :queue => job.queue, + :run_at => Time.now.to_s, + :payload => job.payload + mongo_workers.update({:worker => self.to_s}, { '$set' => { 'working_on' => data}}, :upsert => true) end # Called when we are done working - clears our `working_on` state - # and tells Redis we processed a job. + # and tells Mongo we processed a job. def done_working processed! - redis.del("worker:#{self}") + mongo_workers.remove({ :worker => self.to_s}) end # How many jobs has this worker processed? Returns an int. @@ -379,7 +372,7 @@ def processed Stat["processed:#{self}"] end - # Tell Redis we've processed a job. + # Tell Mongo we've processed a job. def processed! Stat << "processed" Stat << "processed:#{self}" @@ -390,7 +383,7 @@ def failed Stat["failed:#{self}"] end - # Tells Redis we've failed a job. + # Tells Mongo we've failed a job. def failed! Stat << "failed" Stat << "failed:#{self}" @@ -398,17 +391,19 @@ def failed! # What time did this worker start? Returns an instance of `Time` def started - redis.get "worker:#{self}:started" + worker = mongo_workers.find_one(:worker => self.to_s) + worker.nil? ? nil : worker['started'] end - # Tell Redis we've started + # Tell Mongo we've started def started! - redis.set("worker:#{self}:started", Time.now.to_s) + mongo_workers.update({ :worker => self.to_s}, { '$set' => { :started => Time.now.to_s}}) end # Returns a hash explaining the Job we're currently processing, if any. def job - decode(redis.get("worker:#{self}")) || {} + worker = mongo_workers.find_one :worker => self.to_s + worker.nil? ? { } : decode(worker['working_on']) end alias_method :processing, :job @@ -425,7 +420,7 @@ def idle? # Returns a symbol representing the current worker state, # which can be either :working or :idle def state - redis.exists("worker:#{self}") ? :working : :idle + mongo_workers.find_one(:worker => self.to_s) ? :working : :idle end # Is this worker the same as another worker? diff --git a/tasks/redis.rake b/tasks/redis.rake deleted file mode 100644 index 58d8e652d..000000000 --- a/tasks/redis.rake +++ /dev/null @@ -1,159 +0,0 @@ -# Inspired by rabbitmq.rake the Redbox project at http://github.com/rick/redbox/tree/master -require 'fileutils' -require 'open-uri' -require 'pathname' - -class RedisRunner - - def self.redis_dir - @redis_dir ||= if ENV['PREFIX'] - Pathname.new(ENV['PREFIX']) - else - Pathname.new(`which redis-server`) + '..' + '..' - end - end - - def self.bin_dir - redis_dir + 'bin' - end - - def self.config - @config ||= if File.exists?(redis_dir + 'etc/redis.conf') - redis_dir + 'etc/redis.conf' - else - redis_dir + '../etc/redis.conf' - end - end - - def self.dtach_socket - '/tmp/redis.dtach' - end - - # Just check for existance of dtach socket - def self.running? - File.exists? dtach_socket - end - - def self.start - puts 'Detach with Ctrl+\ Re-attach with rake redis:attach' - sleep 1 - command = "#{bin_dir}/dtach -A #{dtach_socket} #{bin_dir}/redis-server #{config}" - sh command - end - - def self.attach - exec "#{bin_dir}/dtach -a #{dtach_socket}" - end - - def self.stop - sh 'echo "SHUTDOWN" | nc localhost 6379' - end - -end - -namespace :redis do - - desc 'About redis' - task :about do - puts "\nSee http://code.google.com/p/redis/ for information about redis.\n\n" - end - - desc 'Start redis' - task :start do - RedisRunner.start - end - - desc 'Stop redis' - task :stop do - RedisRunner.stop - end - - desc 'Restart redis' - task :restart do - RedisRunner.stop - RedisRunner.start - end - - desc 'Attach to redis dtach socket' - task :attach do - RedisRunner.attach - end - - desc 'Install the latest verison of Redis from Github (requires git, duh)' - task :install => [:about, :download, :make] do - bin_dir = '/usr/bin' - conf_dir = '/etc' - - if ENV['PREFIX'] - bin_dir = "#{ENV['PREFIX']}/bin" - sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}") - - conf_dir = "#{ENV['PREFIX']}/etc" - sh "mkdir -p #{conf_dir}" unless File.exists?("#{conf_dir}") - end - - %w(redis-benchmark redis-cli redis-server).each do |bin| - sh "cp /tmp/redis/src/#{bin} #{bin_dir}" - end - - puts "Installed redis-benchmark, redis-cli and redis-server to #{bin_dir}" - - unless File.exists?("#{conf_dir}/redis.conf") - sh "cp /tmp/redis/redis.conf #{conf_dir}/redis.conf" - puts "Installed redis.conf to #{conf_dir} \n You should look at this file!" - end - end - - task :make do - sh "cd /tmp/redis/src && make clean" - sh "cd /tmp/redis/src && make" - end - - desc "Download package" - task :download do - sh 'rm -rf /tmp/redis/' if File.exists?("/tmp/redis/.svn") - sh 'git clone git://github.com/antirez/redis.git /tmp/redis' unless File.exists?('/tmp/redis') - sh "cd /tmp/redis && git pull" if File.exists?("/tmp/redis/.git") - end - -end - -namespace :dtach do - - desc 'About dtach' - task :about do - puts "\nSee http://dtach.sourceforge.net/ for information about dtach.\n\n" - end - - desc 'Install dtach 0.8 from source' - task :install => [:about, :download, :make] do - - bin_dir = "/usr/bin" - - if ENV['PREFIX'] - bin_dir = "#{ENV['PREFIX']}/bin" - sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}") - end - - sh "cp /tmp/dtach-0.8/dtach #{bin_dir}" - end - - task :make do - sh 'cd /tmp/dtach-0.8/ && ./configure && make' - end - - desc "Download package" - task :download do - unless File.exists?('/tmp/dtach-0.8.tar.gz') - require 'net/http' - - url = 'http://downloads.sourceforge.net/project/dtach/dtach/0.8/dtach-0.8.tar.gz' - open('/tmp/dtach-0.8.tar.gz', 'wb') do |file| file.write(open(url).read) end - end - - unless File.directory?('/tmp/dtach-0.8') - sh 'cd /tmp && tar xzf dtach-0.8.tar.gz' - end - end -end - diff --git a/test/redis-test.conf b/test/redis-test.conf deleted file mode 100644 index 0ba01aac0..000000000 --- a/test/redis-test.conf +++ /dev/null @@ -1,115 +0,0 @@ -# Redis configuration file example - -# By default Redis does not run as a daemon. Use 'yes' if you need it. -# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. -daemonize yes - -# When run as a daemon, Redis write a pid file in /var/run/redis.pid by default. -# You can specify a custom pid file location here. -pidfile ./test/redis-test.pid - -# Accept connections on the specified port, default is 6379 -port 9736 - -# If you want you can bind a single interface, if the bind option is not -# specified all the interfaces will listen for connections. -# -# bind 127.0.0.1 - -# Close the connection after a client is idle for N seconds (0 to disable) -timeout 300 - -# Save the DB on disk: -# -# save -# -# Will save the DB if both the given number of seconds and the given -# number of write operations against the DB occurred. -# -# In the example below the behaviour will be to save: -# after 900 sec (15 min) if at least 1 key changed -# after 300 sec (5 min) if at least 10 keys changed -# after 60 sec if at least 10000 keys changed -save 900 1 -save 300 10 -save 60 10000 - -# The filename where to dump the DB -dbfilename dump.rdb - -# For default save/load DB in/from the working directory -# Note that you must specify a directory not a file name. -dir ./test/ - -# Set server verbosity to 'debug' -# it can be one of: -# debug (a lot of information, useful for development/testing) -# notice (moderately verbose, what you want in production probably) -# warning (only very important / critical messages are logged) -loglevel debug - -# Specify the log file name. Also 'stdout' can be used to force -# the demon to log on the standard output. Note that if you use standard -# output for logging but daemonize, logs will be sent to /dev/null -logfile stdout - -# Set the number of databases. The default database is DB 0, you can select -# a different one on a per-connection basis using SELECT where -# dbid is a number between 0 and 'databases'-1 -databases 16 - -################################# REPLICATION ################################# - -# Master-Slave replication. Use slaveof to make a Redis instance a copy of -# another Redis server. Note that the configuration is local to the slave -# so for example it is possible to configure the slave to save the DB with a -# different interval, or to listen to another port, and so on. - -# slaveof - -################################## SECURITY ################################### - -# Require clients to issue AUTH before processing any other -# commands. This might be useful in environments in which you do not trust -# others with access to the host running redis-server. -# -# This should stay commented out for backward compatibility and because most -# people do not need auth (e.g. they run their own servers). - -# requirepass foobared - -################################### LIMITS #################################### - -# Set the max number of connected clients at the same time. By default there -# is no limit, and it's up to the number of file descriptors the Redis process -# is able to open. The special value '0' means no limts. -# Once the limit is reached Redis will close all the new connections sending -# an error 'max number of clients reached'. - -# maxclients 128 - -# Don't use more memory than the specified amount of bytes. -# When the memory limit is reached Redis will try to remove keys with an -# EXPIRE set. It will try to start freeing keys that are going to expire -# in little time and preserve keys with a longer time to live. -# Redis will also try to remove objects from free lists if possible. -# -# If all this fails, Redis will start to reply with errors to commands -# that will use more memory, like SET, LPUSH, and so on, and will continue -# to reply to most read-only commands like GET. -# -# WARNING: maxmemory can be a good idea mainly if you want to use Redis as a -# 'state' server or cache, not as a real DB. When Redis is used as a real -# database the memory usage will grow over the weeks, it will be obvious if -# it is going to use too much memory in the long run, and you'll have the time -# to upgrade. With maxmemory after the limit is reached you'll start to get -# errors for write operations, and this may even lead to DB inconsistency. - -# maxmemory - -############################### ADVANCED CONFIG ############################### - -# Glue small output buffers together in order to send small replies in a -# single TCP packet. Uses a bit more CPU but most of the times it is a win -# in terms of number of queries per second. Use 'yes' if unsure. -glueoutputbuf yes diff --git a/test/resque_test.rb b/test/resque_test.rb index 3cba3d8d1..bdb1df74d 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -2,7 +2,7 @@ context "Resque" do setup do - Resque.redis.flushall + Resque.drop Resque.push(:people, { 'name' => 'chris' }) Resque.push(:people, { 'name' => 'bob' }) @@ -10,10 +10,10 @@ end test "can set a namespace through a url-like string" do - assert Resque.redis - assert_equal :resque, Resque.redis.namespace - Resque.redis = 'localhost:9736/namespace' - assert_equal 'namespace', Resque.redis.namespace + assert Resque.mongo + assert_equal 'resque', Resque.mongo.name + Resque.mongo = 'localhost:27017/namespace' + assert_equal 'namespace', Resque.mongo.name end test "can put jobs on a queue" do @@ -132,36 +132,48 @@ assert Resque.push(:people, { 'name' => 'jon' }) end + def pop_no_id(queue) + item = Resque.pop(queue) + item.delete("_id") + item + end + + test "can pull items off a queue" do - assert_equal({ 'name' => 'chris' }, Resque.pop(:people)) - assert_equal({ 'name' => 'bob' }, Resque.pop(:people)) - assert_equal({ 'name' => 'mark' }, Resque.pop(:people)) + assert_equal({ 'name' => 'chris' }, pop_no_id(:people)) + assert_equal({ 'name' => 'bob' }, pop_no_id(:people)) + assert_equal({ 'name' => 'mark' }, pop_no_id(:people)) assert_equal nil, Resque.pop(:people) end test "knows how big a queue is" do assert_equal 3, Resque.size(:people) - assert_equal({ 'name' => 'chris' }, Resque.pop(:people)) + assert_equal({ 'name' => 'chris' }, pop_no_id(:people)) assert_equal 2, Resque.size(:people) - assert_equal({ 'name' => 'bob' }, Resque.pop(:people)) - assert_equal({ 'name' => 'mark' }, Resque.pop(:people)) + assert_equal({ 'name' => 'bob' }, pop_no_id(:people)) + assert_equal({ 'name' => 'mark' }, pop_no_id(:people)) assert_equal 0, Resque.size(:people) end test "can peek at a queue" do - assert_equal({ 'name' => 'chris' }, Resque.peek(:people)) + peek = Resque.peek(:people) + peek.delete "_id" + assert_equal({ 'name' => 'chris' }, peek) assert_equal 3, Resque.size(:people) end test "can peek multiple items on a queue" do - assert_equal({ 'name' => 'bob' }, Resque.peek(:people, 1, 1)) - - assert_equal([{ 'name' => 'bob' }, { 'name' => 'mark' }], Resque.peek(:people, 1, 2)) - assert_equal([{ 'name' => 'chris' }, { 'name' => 'bob' }], Resque.peek(:people, 0, 2)) - assert_equal([{ 'name' => 'chris' }, { 'name' => 'bob' }, { 'name' => 'mark' }], Resque.peek(:people, 0, 3)) - assert_equal({ 'name' => 'mark' }, Resque.peek(:people, 2, 1)) + assert_equal('bob', Resque.peek(:people, 1, 1)['name']) + peek = Resque.peek(:people, 1, 2).map { |hash| { 'name' => hash['name']}} + assert_equal([{ 'name' => 'bob' }, { 'name' => 'mark' }], peek) + peek = Resque.peek(:people, 0, 2).map { |hash| { 'name' => hash['name']} } + assert_equal([{ 'name' => 'chris' }, { 'name' => 'bob' }], peek) + peek = Resque.peek(:people, 0, 3).map { |hash| { 'name' => hash['name']} } + assert_equal([{ 'name' => 'chris' }, { 'name' => 'bob' }, { 'name' => 'mark' }], peek) + peek = Resque.peek(:people, 2, 1) + assert_equal('mark', peek['name']) assert_equal nil, Resque.peek(:people, 3) assert_equal [], Resque.peek(:people, 3, 2) end @@ -169,24 +181,24 @@ test "knows what queues it is managing" do assert_equal %w( people ), Resque.queues Resque.push(:cars, { 'make' => 'bmw' }) - assert_equal %w( cars people ), Resque.queues + assert_equal %w( cars people ), Resque.queues.sort end test "queues are always a list" do - Resque.redis.flushall + Resque.drop assert_equal [], Resque.queues end test "can delete a queue" do Resque.push(:cars, { 'make' => 'bmw' }) - assert_equal %w( cars people ), Resque.queues + assert_equal %w( cars people ), Resque.queues.sort Resque.remove_queue(:people) assert_equal %w( cars ), Resque.queues assert_equal nil, Resque.pop(:people) end test "keeps track of resque keys" do - assert_equal ["queue:people", "queues"], Resque.keys + assert Resque.keys.include? 'people' end test "badly wants a class name, too" do @@ -223,26 +235,12 @@ assert_equal 3, stats[:queues] assert_equal 3, stats[:processed] assert_equal 1, stats[:failed] - assert_equal [Resque.redis.respond_to?(:server) ? 'localhost:9736' : 'redis://localhost:9736/0'], stats[:servers] + # assert_equal [Resque.redis.respond_to?(:server) ? 'localhost:9736' : 'redis://localhost:9736/0'], stats[:servers] end test "decode bad json" do assert_nil Resque.decode("{\"error\":\"Module not found \\u002\"}") end -=begin - class UniqueJob - @queue = :unique - @unique_jobs = true - end - - class NonUnique - @queue = :unique - end - - class OtherUnique - @queue = :unique2 - @unique_jobs = true - end test "unique jobs are unique" do #does uniqueness work? @@ -277,5 +275,5 @@ class OtherUnique assert_equal(6, Resque.size(:unique)) assert_equal('my args4', Resque.peek(:unique, 5)['args'][0]['arg1']) end -=end + end diff --git a/test/test_helper.rb b/test/test_helper.rb index 71474c6b6..7e5f5fe99 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- dir = File.dirname(File.expand_path(__FILE__)) $LOAD_PATH.unshift dir + '/../lib' $TESTING = true @@ -10,44 +11,11 @@ rescue LoadError end - -# -# make sure we can run redis -# - -if !system("which redis-server") - puts '', "** can't find `redis-server` in your path" - puts "** try running `sudo rake install`" - abort '' -end - - # # start our own redis when the tests start, # kill it when they end # -at_exit do - next if $! - - if defined?(MiniTest) - exit_code = MiniTest::Unit.new.run(ARGV) - else - exit_code = Test::Unit::AutoRunner.run - end - - pid = `ps -A -o pid,command | grep [r]edis-test`.split(" ")[0] - puts "Killing test redis server..." - `rm -f #{dir}/dump.rdb` - Process.kill("KILL", pid.to_i) - exit exit_code -end - -puts "Starting redis for testing at localhost:9736..." -`redis-server #{dir}/redis-test.conf` -Resque.redis = 'localhost:9736' - - ## # test/spec/mini 3 # http://gist.github.com/25455 @@ -114,3 +82,66 @@ def self.perform raise SyntaxError, "Extra Bad job!" end end + +class UniqueJob + @queue = :unique + @unique_jobs = true +end + +class NonUnique + @queue = :unique +end + +class OtherUnique + @queue = :unique2 + @unique_jobs = true +end + + +#some redgreen fun +# -*- coding: utf-8 -*- +begin + require 'redgreen' + module Test + module Unit + module UI + module Console + class TestRunner + def test_started(name) + @individual_test_start_time = Time.now + output_single(name + ": ", VERBOSE) + end + + def test_finished(name) + elapsed_test_time = Time.now - @individual_test_start_time + char_to_output = elapsed_test_time > 1 ? "☻" : "." + output_single(char_to_output, PROGRESS_ONLY) unless (@already_outputted) + nl(VERBOSE) + @already_outputted = false + end + end + end + end + end + end + + # -*- coding: utf-8 -*- + class Test::Unit::UI::Console::RedGreenTestRunner < Test::Unit::UI::Console::TestRunner + def output_single(something, level=NORMAL) + return unless (output?(level)) + something = case something + when '.' then Color.green('.') + when '☻' then Color.green('☻') + when 'F' then Color.red("F") + when 'E' then Color.yellow("E") + when '+' then Color.green('+') + else something + end + @io.write(something) + @io.flush + end + end +rescue LoadError + puts "consider gem install redgreen" +end + diff --git a/test/worker_test.rb b/test/worker_test.rb index e2bad28d8..c01af02a2 100644 --- a/test/worker_test.rb +++ b/test/worker_test.rb @@ -2,7 +2,7 @@ context "Resque::Worker" do setup do - Resque.redis.flushall + Resque.drop Resque.before_first_fork = nil Resque.before_fork = nil @@ -260,7 +260,7 @@ end test "Will call a before_first_fork hook only once" do - Resque.redis.flushall + Resque.drop $BEFORE_FORK_CALLED = 0 Resque.before_first_fork = Proc.new { $BEFORE_FORK_CALLED += 1 } workerA = Resque::Worker.new(:jobs) @@ -277,7 +277,7 @@ end test "Will call a before_fork hook before forking" do - Resque.redis.flushall + Resque.drop $BEFORE_FORK_CALLED = false Resque.before_fork = Proc.new { $BEFORE_FORK_CALLED = true } workerA = Resque::Worker.new(:jobs) @@ -289,7 +289,7 @@ end test "Will call an after_fork hook after forking" do - Resque.redis.flushall + Resque.drop $AFTER_FORK_CALLED = false Resque.after_fork = Proc.new { $AFTER_FORK_CALLED = true } workerA = Resque::Worker.new(:jobs) From 9cdd035990ecdae10c44eb22db710b3211cd0612 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 28 Sep 2010 16:31:14 -0400 Subject: [PATCH 23/59] some worker cleanup --- lib/resque.rb | 9 ++++---- lib/resque/helpers.rb | 2 +- lib/resque/job.rb | 1 + lib/resque/worker.rb | 10 ++++----- test/resque_test.rb | 3 +++ test/test_helper.rb | 52 ++++++------------------------------------- test/worker_test.rb | 24 +++++++++++++++----- 7 files changed, 41 insertions(+), 60 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index fe812a266..edb9e1616 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -56,7 +56,7 @@ def mongo end def mongo_db=(db) - @mongo.conn.db = db + mongo.conn.db = db end @@ -143,7 +143,7 @@ def push(queue, item) # # Returns a Ruby object. def pop(queue) - mongo[queue].find_and_modify(:sort => [:natural, :desc], :remove => true ) + item = mongo[queue].find_and_modify(:sort => [:natural, :desc], :remove => true ) rescue Mongo::OperationFailure => e return nil if e.message =~ /No matching object/ raise e @@ -297,11 +297,12 @@ def info # is O(N) for the keyspace, so be careful - this can be slow for big databases. def keys names = mongo.collection_names - #names.delete_if{ |name| name == 'system.indexes' || name =~ /resque\./ } end def drop - mongo.collections.each{ |collection| collection.drop unless collection.name =~ /^system./ } + mongo.collections.each{ |collection| collection.drop unless collection.name =~ /^system./ + # puts "dropping #{collection.name}" unless collection.name =~ /^system./} + } @mongo = nil end end diff --git a/lib/resque/helpers.rb b/lib/resque/helpers.rb index 9c9a175ce..fbb57ba0f 100644 --- a/lib/resque/helpers.rb +++ b/lib/resque/helpers.rb @@ -23,7 +23,7 @@ def encode(object) object.to_json end end - + # Given a string, returns a Ruby object. def decode(object) return unless object diff --git a/lib/resque/job.rb b/lib/resque/job.rb index 41ffed6da..0e9ea5e5e 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -32,6 +32,7 @@ class Job def initialize(queue, payload) @queue = queue @payload = payload + end # Creates a job by placing it on a queue. Expects a string queue diff --git a/lib/resque/worker.rb b/lib/resque/worker.rb index d6f75a116..80a7b0efc 100644 --- a/lib/resque/worker.rb +++ b/lib/resque/worker.rb @@ -353,10 +353,10 @@ def unregister_worker # what workers are doing and when. def working_on(job) job.worker = self - data = encode \ - :queue => job.queue, - :run_at => Time.now.to_s, - :payload => job.payload + data = #encode \ + { :queue => job.queue, + :run_at => Time.now.to_s, + :payload => job.payload} mongo_workers.update({:worker => self.to_s}, { '$set' => { 'working_on' => data}}, :upsert => true) end @@ -403,7 +403,7 @@ def started! # Returns a hash explaining the Job we're currently processing, if any. def job worker = mongo_workers.find_one :worker => self.to_s - worker.nil? ? { } : decode(worker['working_on']) + worker.nil? ? { } : worker['working_on'] #decode(worker['working_on']) end alias_method :processing, :job diff --git a/test/resque_test.rb b/test/resque_test.rb index bdb1df74d..d49d4f595 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -242,6 +242,7 @@ def pop_no_id(queue) assert_nil Resque.decode("{\"error\":\"Module not found \\u002\"}") end +=begin test "unique jobs are unique" do #does uniqueness work? Resque.enqueue(UniqueJob, {:_id => 'my_id', :arg1=> 'my args1'}) @@ -276,4 +277,6 @@ def pop_no_id(queue) assert_equal('my args4', Resque.peek(:unique, 5)['args'][0]['arg1']) end +=end + end diff --git a/test/test_helper.rb b/test/test_helper.rb index 7e5f5fe99..8cae2b8d9 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -90,6 +90,11 @@ class UniqueJob class NonUnique @queue = :unique + + def self.perform(data) + "I has a #{data}" + end + end class OtherUnique @@ -99,49 +104,6 @@ class OtherUnique #some redgreen fun -# -*- coding: utf-8 -*- -begin - require 'redgreen' - module Test - module Unit - module UI - module Console - class TestRunner - def test_started(name) - @individual_test_start_time = Time.now - output_single(name + ": ", VERBOSE) - end - - def test_finished(name) - elapsed_test_time = Time.now - @individual_test_start_time - char_to_output = elapsed_test_time > 1 ? "☻" : "." - output_single(char_to_output, PROGRESS_ONLY) unless (@already_outputted) - nl(VERBOSE) - @already_outputted = false - end - end - end - end - end - end - - # -*- coding: utf-8 -*- - class Test::Unit::UI::Console::RedGreenTestRunner < Test::Unit::UI::Console::TestRunner - def output_single(something, level=NORMAL) - return unless (output?(level)) - something = case something - when '.' then Color.green('.') - when '☻' then Color.green('☻') - when 'F' then Color.red("F") - when 'E' then Color.yellow("E") - when '+' then Color.green('+') - else something - end - @io.write(something) - @io.flush - end - end -rescue LoadError - puts "consider gem install redgreen" -end + + diff --git a/test/worker_test.rb b/test/worker_test.rb index c01af02a2..403d9bb21 100644 --- a/test/worker_test.rb +++ b/test/worker_test.rb @@ -3,11 +3,9 @@ context "Resque::Worker" do setup do Resque.drop - Resque.before_first_fork = nil Resque.before_fork = nil Resque.after_fork = nil - @worker = Resque::Worker.new(:jobs) Resque::Job.create(:jobs, SomeJob, 20, '/tmp') end @@ -26,7 +24,7 @@ end test "fails uncompleted jobs on exit" do - job = Resque::Job.new(:jobs, [GoodJob, "blah"]) + job = Resque::Job.new(:jobs, ['GoodJob', "blah"]) @worker.working_on(job) @worker.unregister_worker assert_equal 1, Resque::Failure.count @@ -143,9 +141,10 @@ test "records what it is working on" do @worker.work(0) do task = @worker.job + task['payload'].delete "_id" assert_equal({"args"=>[20, "/tmp"], "class"=>"SomeJob"}, task['payload']) assert task['run_at'] - assert_equal 'jobs', task['queue'] + assert_equal 'jobs', task['queue'].to_s end end @@ -213,10 +212,11 @@ end end + #this test depends on some OS-specific behavior test "sets $0 while working" do @worker.work(0) do ver = Resque::Version - assert_equal "resque-#{ver}: Processing jobs since #{Time.now.to_i}", $0 + assert_equal "resque-#{ver}: Processing jobs since #{Time.now.to_i}"[0..$0.length-1], $0 end end @@ -299,4 +299,18 @@ workerA.work(0) assert $AFTER_FORK_CALLED end + +=begin + test "Can bypass queues for testing" do + #Resque.drop + #Resque.enqueue(NonUnique, 'test') + #assert_equal(1, Resque.size(:unique)) + #Resque.bypass_queues = true + #Resque.enqueue(NonUnique, 'test') + #assert_equal(1, Resque.size(:unique)) + #Resque.bypass_queues = false + #Resque.enqueue(NonUnique, 'test') + #assert_equal(2, Resque.size(:unique)) + end +=end end From 031f4d7b6f50f82b3db8b60e583c73024031e60e Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 28 Sep 2010 17:04:18 -0400 Subject: [PATCH 24/59] implement bypass_queues --- lib/resque.rb | 15 ++++++++++----- test/resque_test.rb | 8 +++----- test/test_helper.rb | 5 ----- test/worker_test.rb | 21 +++++++++------------ 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index edb9e1616..931a4696c 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -23,7 +23,10 @@ module Resque include Helpers extend self - + attr_accessor :bypass_queues + @bypass_queues = false + + def mongo=(server) if server.is_a? String opts = server.split(':') @@ -203,7 +206,11 @@ def remove_queue(queue) # # This method is considered part of the `stable` API. def enqueue(klass, *args) - Job.create(queue_from_class(klass), klass, *args) + if @bypass_queues + klass.send(:perform, *args) + else + Job.create(queue_from_class(klass), klass, *args) + end end # This method can be used to conveniently remove a job from a queue. @@ -300,9 +307,7 @@ def keys end def drop - mongo.collections.each{ |collection| collection.drop unless collection.name =~ /^system./ - # puts "dropping #{collection.name}" unless collection.name =~ /^system./} - } + mongo.collections.each{ |collection| collection.drop unless collection.name =~ /^system./ } @mongo = nil end end diff --git a/test/resque_test.rb b/test/resque_test.rb index d49d4f595..5a0514163 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -242,8 +242,8 @@ def pop_no_id(queue) assert_nil Resque.decode("{\"error\":\"Module not found \\u002\"}") end -=begin - test "unique jobs are unique" do + test "unique jobs are unique" do + #does uniqueness work? Resque.enqueue(UniqueJob, {:_id => 'my_id', :arg1=> 'my args1'}) assert_equal(1, Resque.size(:unique)) @@ -275,8 +275,6 @@ def pop_no_id(queue) Resque.enqueue(UniqueJob, {:arg1=> 'my args4'}) assert_equal(6, Resque.size(:unique)) assert_equal('my args4', Resque.peek(:unique, 5)['args'][0]['arg1']) - end - -=end + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 8cae2b8d9..c2e1b8222 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -102,8 +102,3 @@ class OtherUnique @unique_jobs = true end - -#some redgreen fun - - - diff --git a/test/worker_test.rb b/test/worker_test.rb index 403d9bb21..0f3a89e29 100644 --- a/test/worker_test.rb +++ b/test/worker_test.rb @@ -300,17 +300,14 @@ assert $AFTER_FORK_CALLED end -=begin test "Can bypass queues for testing" do - #Resque.drop - #Resque.enqueue(NonUnique, 'test') - #assert_equal(1, Resque.size(:unique)) - #Resque.bypass_queues = true - #Resque.enqueue(NonUnique, 'test') - #assert_equal(1, Resque.size(:unique)) - #Resque.bypass_queues = false - #Resque.enqueue(NonUnique, 'test') - #assert_equal(2, Resque.size(:unique)) - end -=end + Resque.enqueue(NonUnique, 'test') + assert_equal(1, Resque.size(:unique)) + Resque.bypass_queues = true + Resque.enqueue(NonUnique, 'test') + assert_equal(1, Resque.size(:unique)) + Resque.bypass_queues = false + Resque.enqueue(NonUnique, 'test') + assert_equal(2, Resque.size(:unique)) + end end From d6090f76d750dafb4c69891f70be9b6efc4fdccf Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 28 Sep 2010 17:08:03 -0400 Subject: [PATCH 25/59] added resque-igo gemspec --- resque-igo.gemspec | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 resque-igo.gemspec diff --git a/resque-igo.gemspec b/resque-igo.gemspec new file mode 100644 index 000000000..df64d8f71 --- /dev/null +++ b/resque-igo.gemspec @@ -0,0 +1,47 @@ +$LOAD_PATH.unshift 'lib' +require 'resque/version' + +Gem::Specification.new do |s| + s.name = "resque" + s.version = Resque::Version + s.date = Time.now.strftime('%Y-%m-%d') + s.summary = "Resque-igo is a mongo-backed queueing system" + s.homepage = "http://github.com/naginata/resque-mongo" + s.email = "naginata@gmail.com" + s.authors = [ "Nathan D Acuff" ] + + s.files = %w( README.markdown Rakefile LICENSE HISTORY.md ) + s.files += Dir.glob("lib/**/*") + s.files += Dir.glob("bin/**/*") + s.files += Dir.glob("man/**/*") + s.files += Dir.glob("test/**/*") + s.files += Dir.glob("tasks/**/*") + s.executables = [ "resque", "resque-web" ] + + s.extra_rdoc_files = [ "LICENSE", "README.markdown" ] + s.rdoc_options = ["--charset=UTF-8"] + + s.add_dependency "vegas", "~> 0.1.2" + s.add_dependency "sinatra", ">= 0.9.2" + s.add_dependency "json", "~> 1.4.6" + s.add_dependency "mongo", ">= 1.0.7" + + s.description = < Date: Tue, 28 Sep 2010 17:50:02 -0400 Subject: [PATCH 26/59] proper name for gem --- resque-igo.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resque-igo.gemspec b/resque-igo.gemspec index df64d8f71..b2830987c 100644 --- a/resque-igo.gemspec +++ b/resque-igo.gemspec @@ -2,7 +2,7 @@ $LOAD_PATH.unshift 'lib' require 'resque/version' Gem::Specification.new do |s| - s.name = "resque" + s.name = "resque-igo" s.version = Resque::Version s.date = Time.now.strftime('%Y-%m-%d') s.summary = "Resque-igo is a mongo-backed queueing system" From c2bc4ff82ee0ea856153242608956fe6f5dbf228 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 29 Sep 2010 10:25:26 -0400 Subject: [PATCH 27/59] implemented unique tasks --- lib/resque.rb | 10 +++++++++- lib/resque/job.rb | 14 +++++++++++++- test/resque_test.rb | 3 --- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index 931a4696c..d0ec5144b 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -131,6 +131,10 @@ def to_s "Resque Client connected to #{mongo.connection.host}:#{mongo.connection.port}/#{mongo.name}" end + def allows_unique_jobs(klass) + klass.instance_variable_get(:@unique_jobs) || + (klass.respond_to?(:unique_jobs) and klass.unique_jobs) + end # # queue manipulation @@ -139,7 +143,11 @@ def to_s # Pushes a job onto a queue. Queue name should be a string and the # item should be any JSON-able Ruby object. def push(queue, item) - mongo[queue] << item + if item[:unique] + mongo[queue].update({'_id' => item[:_id]}, item, { :upsert => true}) + else + mongo[queue] << item + end end # Pops a job off a queue. Queue name should be a string. diff --git a/lib/resque/job.rb b/lib/resque/job.rb index 0e9ea5e5e..32722b676 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -49,7 +49,19 @@ def self.create(queue, klass, *args) raise NoClassError.new("Jobs must be given a class.") end - ret = Resque.push(queue, :class => klass.to_s, :args => args) + item = { :class => klass.to_s, :args => args} + if Resque.allows_unique_jobs(klass) + if args.is_a?(Hash) && args.has_key?(:_id) + item[:_id] = args[:_id] + elsif args.is_a? Array + if args[0].is_a?(Hash) && args[0].has_key?(:_id) + item[:_id] = args[0][:_id] + end + end + end + item[:unique] = true if item[:_id] + + ret = Resque.push(queue, item) Plugin.after_enqueue_hooks(klass).each do |hook| klass.send(hook, *args) end diff --git a/test/resque_test.rb b/test/resque_test.rb index 5a0514163..8f09b1d29 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -243,7 +243,6 @@ def pop_no_id(queue) end test "unique jobs are unique" do - #does uniqueness work? Resque.enqueue(UniqueJob, {:_id => 'my_id', :arg1=> 'my args1'}) assert_equal(1, Resque.size(:unique)) @@ -254,7 +253,6 @@ def pop_no_id(queue) assert_equal('my args2', Resque.peek(:unique)['args'][0]['arg1']) #if I enqueue unique jobs with the same key in 2 queues, do I get 2 jobs? - puts 'here we go' Resque.enqueue(UniqueJob, {:_id => 'my_id3', :arg1=> 'my arg3'}) assert_equal(2, Resque.size(:unique)) Resque.enqueue(OtherUnique, {:_id => 'my_id3', :arg1=> 'my args4'}) @@ -275,6 +273,5 @@ def pop_no_id(queue) Resque.enqueue(UniqueJob, {:arg1=> 'my args4'}) assert_equal(6, Resque.size(:unique)) assert_equal('my args4', Resque.peek(:unique, 5)['args'][0]['arg1']) - end end From 4497018f6c71efffeb0e4e7defa602cb56bada43 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 29 Sep 2010 10:38:31 -0400 Subject: [PATCH 28/59] simplified the unique-id lookup in job creation --- lib/resque/job.rb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/resque/job.rb b/lib/resque/job.rb index 32722b676..6ba56922f 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -50,15 +50,7 @@ def self.create(queue, klass, *args) end item = { :class => klass.to_s, :args => args} - if Resque.allows_unique_jobs(klass) - if args.is_a?(Hash) && args.has_key?(:_id) - item[:_id] = args[:_id] - elsif args.is_a? Array - if args[0].is_a?(Hash) && args[0].has_key?(:_id) - item[:_id] = args[0][:_id] - end - end - end + item[:_id] = args[0][:_id] if Resque.allows_unique_jobs(klass) && args.is_a?(Array) && args[0].is_a?(Hash) && args[0].has_key?(:_id) item[:unique] = true if item[:_id] ret = Resque.push(queue, item) From 587ef6765ed522f35f117834d00ec7553cc18d4e Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 29 Sep 2010 13:40:58 -0400 Subject: [PATCH 29/59] adds some instructions to readme --- README.markdown | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/README.markdown b/README.markdown index 1ade9a768..25ffe07e5 100644 --- a/README.markdown +++ b/README.markdown @@ -30,6 +30,48 @@ not doing, what queues you're using, what's in those queues, provides general usage stats, and helps you track failures. +What did you guys do to Resque? +=============================== + +This version of Resque uses mongo as the back end. It also has some neat +new features that you may enjoy + +Features +-------- + +It stores each queue in its own collection. + +For testing purposes. Resque.bypass_queues will call your job's +perform method AT ONCE, and not touch the queue at all. This can be +useful when writing unit tests against things that would normally +happen partially in your request and partially in a worker. + +If your job object has a variable called @unique_jobs = true, you +can queue unique jobs - jobs that must only be processed once. In +order to take advantage of this feature, the arguments to your enqueue +call must include a hash containing a key called _id in the first +position. + +Stern Warnings +-------------- + +Sometimes, Resque-Mongo will drop a queue collection, or create some +indexes, or otherwise manipulate its database. For this reason, it is +STRONGLY recommended that you give it its own database in mongo. + +All jobs should be queued via Resque.enqueue. All arguments passed to +this method must be BSON-encodable. Resque-Mongo does not serialize +your objects for you. Arrays, Hashes, Strings, Numbers, and Times +are all ok, so don't worry. + +Many of the new queue-level features require the first argument of +your perform method to be an options hash. In fact, if you just start +making all your perform()s take one param, that is an options hash, +you'll probably save yourself some pain. + +Back to the original README +=========================== + The Blog Post ------------- From 043dfa93ed01cc9f01d8335f6d63b9868ce7f1b3 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 29 Sep 2010 13:56:07 -0400 Subject: [PATCH 30/59] moves a test, updates README --- README.markdown | 8 ++++++++ test/resque_test.rb | 11 +++++++++++ test/worker_test.rb | 11 ----------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/README.markdown b/README.markdown index 25ffe07e5..e8e7f0672 100644 --- a/README.markdown +++ b/README.markdown @@ -69,6 +69,14 @@ your perform method to be an options hash. In fact, if you just start making all your perform()s take one param, that is an options hash, you'll probably save yourself some pain. +Resque-Mongo will not create any indexes on your queues, only on its +meta-data. You will need to create any indexes you want. Normally, +This is not a problem, because you aren't querying by keys, but you may +want to create indexes on the class key. If you use the unique or +wait features, you may want some additional indexes, depending on +the nature of your workload. Paranoid? Test enqueuing and processing +all your jobs, and run with --notablescans. + Back to the original README =========================== diff --git a/test/resque_test.rb b/test/resque_test.rb index 8f09b1d29..f83957d42 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -274,4 +274,15 @@ def pop_no_id(queue) assert_equal(6, Resque.size(:unique)) assert_equal('my args4', Resque.peek(:unique, 5)['args'][0]['arg1']) end + + test "Can bypass queues for testing" do + Resque.enqueue(NonUnique, 'test') + assert_equal(1, Resque.size(:unique)) + Resque.bypass_queues = true + Resque.enqueue(NonUnique, 'test') + assert_equal(1, Resque.size(:unique)) + Resque.bypass_queues = false + Resque.enqueue(NonUnique, 'test') + assert_equal(2, Resque.size(:unique)) + end end diff --git a/test/worker_test.rb b/test/worker_test.rb index 0f3a89e29..3016b334d 100644 --- a/test/worker_test.rb +++ b/test/worker_test.rb @@ -299,15 +299,4 @@ workerA.work(0) assert $AFTER_FORK_CALLED end - - test "Can bypass queues for testing" do - Resque.enqueue(NonUnique, 'test') - assert_equal(1, Resque.size(:unique)) - Resque.bypass_queues = true - Resque.enqueue(NonUnique, 'test') - assert_equal(1, Resque.size(:unique)) - Resque.bypass_queues = false - Resque.enqueue(NonUnique, 'test') - assert_equal(2, Resque.size(:unique)) - end end From 177ab3a9b0698003390902af5cf2e3e0704f5c4e Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Thu, 30 Sep 2010 12:57:44 -0400 Subject: [PATCH 31/59] implements delayed jobs --- README.markdown | 21 +++++++++---- lib/resque.rb | 32 ++++++++++++++++++-- lib/resque/job.rb | 4 ++- lib/resque/server/views/queues.erb | 7 +++-- test/resque_test.rb | 48 +++++++++++++++++++++++++++++- test/test_helper.rb | 13 ++++++++ 6 files changed, 114 insertions(+), 11 deletions(-) diff --git a/README.markdown b/README.markdown index e8e7f0672..d2b20b403 100644 --- a/README.markdown +++ b/README.markdown @@ -46,12 +46,18 @@ perform method AT ONCE, and not touch the queue at all. This can be useful when writing unit tests against things that would normally happen partially in your request and partially in a worker. -If your job object has a variable called @unique_jobs = true, you +If your job class has a variable called @unique_jobs = true, you can queue unique jobs - jobs that must only be processed once. In order to take advantage of this feature, the arguments to your enqueue call must include a hash containing a key called _id in the first position. +If your job class indicates that @delayed_jobs = true, you can queue +delayed jobs. These jobs will not be popped off the queue until the +Time indicated in arg[0][:delay_until] has come. Note that you must +call Resque.enable_delay(:queue) before enququing any delayed jobs, to +ensure that the performance impact on other queues is minimal. + Stern Warnings -------------- @@ -72,10 +78,15 @@ you'll probably save yourself some pain. Resque-Mongo will not create any indexes on your queues, only on its meta-data. You will need to create any indexes you want. Normally, This is not a problem, because you aren't querying by keys, but you may -want to create indexes on the class key. If you use the unique or -wait features, you may want some additional indexes, depending on -the nature of your workload. Paranoid? Test enqueuing and processing -all your jobs, and run with --notablescans. +want to create indexes on the class key in some circumstances. If you +use the unique or delay features, you may want some additional indexes, +depending on the nature of your workload. Paranoid? Test enqueuing and +processing all your jobs, and run with --notablescans. Learn the profiler, +and use it often. + +Specifically, a queue with many long-delayed jobs will result in slower queue pops +for all jobs using that queue. Index delay_until in the case of +thousands of delayed jobs. Back to the original README =========================== diff --git a/lib/resque.rb b/lib/resque.rb index d0ec5144b..7f7d676ab 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -25,6 +25,7 @@ module Resque extend self attr_accessor :bypass_queues @bypass_queues = false + @delay_allowed = [] def mongo=(server) @@ -136,6 +137,15 @@ def allows_unique_jobs(klass) (klass.respond_to?(:unique_jobs) and klass.unique_jobs) end + def allows_delayed_jobs(klass) + klass.instance_variable_get(:@delayed_jobs) || + (klass.respond_to?(:delayed_jobs) and klass.delayed_jobs) + end + + def enable_delay(queue) + @delay_allowed << queue unless @delay_allowed.include? queue + end + # # queue manipulation # @@ -154,7 +164,11 @@ def push(queue, item) # # Returns a Ruby object. def pop(queue) - item = mongo[queue].find_and_modify(:sort => [:natural, :desc], :remove => true ) + query = { } + if @delay_allowed.include? queue + query['delay_until'] = { '$not' => { '$gt' => Time.new}} + end + item = mongo[queue].find_and_modify(:query => query, :sort => [:natural, :desc], :remove => true ) rescue Mongo::OperationFailure => e return nil if e.message =~ /No matching object/ raise e @@ -163,9 +177,19 @@ def pop(queue) # Returns an integer representing the size of a queue. # Queue name should be a string. def size(queue) + + if @delay_allowed.include? queue + mongo[queue].find({'delay_until' => { '$not' => { '$gt' => Time.new}}}).count + else + mongo[queue].count + end + end + + def raw_size(queue) mongo[queue].count end + # Returns an array of items currently queued. Queue name should be # a string. # @@ -181,7 +205,11 @@ def peek(queue, start = 0, count = 1) # Does the dirty work of fetching a range of items from a Redis list # and converting them into Ruby objects. def list_range(key, start = 0, count = 1) - items = mongo[key].find({ }, { :limit => count, :skip => start}).to_a.map{ |i| i} + query = { } + if @delay_allowed.include? key + query['delay_until'] = { '$not' => { '$gt' => Time.new}} + end + items = mongo[key].find(query, { :limit => count, :skip => start}).to_a.map{ |i| i} count > 1 ? items : items.first end diff --git a/lib/resque/job.rb b/lib/resque/job.rb index 6ba56922f..df42a5c8f 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -50,8 +50,10 @@ def self.create(queue, klass, *args) end item = { :class => klass.to_s, :args => args} - item[:_id] = args[0][:_id] if Resque.allows_unique_jobs(klass) && args.is_a?(Array) && args[0].is_a?(Hash) && args[0].has_key?(:_id) + item[:_id] = args[0][:_id] if Resque.allows_unique_jobs(klass) && args[0].is_a?(Hash) && args[0].has_key?(:_id) item[:unique] = true if item[:_id] + item[:delay_until] = args[0][:delay_until] if Resque.allows_delayed_jobs(klass) && args[0].is_a?(Hash) && args[0].has_key?(:delay_until) + ret = Resque.push(queue, item) Plugin.after_enqueue_hooks(klass).each do |hook| diff --git a/lib/resque/server/views/queues.erb b/lib/resque/server/views/queues.erb index 8025561cf..ae95fd06c 100644 --- a/lib/resque/server/views/queues.erb +++ b/lib/resque/server/views/queues.erb @@ -6,7 +6,10 @@
" class='remove-queue'>
-

Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <%=size = resque.size(queue)%> jobs

+

Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <%=size = resque.size(queue.to_sym)%> jobs

+ <% if size != resque.raw_size(queue.to_sym) %> +

Delayed Jobs: <%= resque.raw_size(queue.to_sym)%>

+ <% end %> @@ -37,7 +40,7 @@ <% for queue in resque.queues.sort_by { |q| q.to_s } %> - + <% end %> "> diff --git a/test/resque_test.rb b/test/resque_test.rb index f83957d42..352000dfe 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -3,7 +3,8 @@ context "Resque" do setup do Resque.drop - + Resque.bypass_queues = false + Resque.enable_delay(:delayed) Resque.push(:people, { 'name' => 'chris' }) Resque.push(:people, { 'name' => 'bob' }) Resque.push(:people, { 'name' => 'mark' }) @@ -285,4 +286,49 @@ def pop_no_id(queue) Resque.enqueue(NonUnique, 'test') assert_equal(2, Resque.size(:unique)) end + + test "delayed jobs work" do + args = { :delay_until => Time.new-1} + Resque.enqueue(DelayedJob, args) + job = Resque::Job.reserve(:delayed) + assert_equal(1, job.args[0].keys.length) + assert_equal(args[:delay_until].to_i, job.args[0]["delay_until"].to_i) + args[:delay_until] = Time.new + 2 + Resque.enqueue(DelayedJob, args) + + assert_equal(0, Resque.size(:delayed)) + assert_nil Resque.peek(:delayed) + assert_nil Resque::Job.reserve(:delayed) + sleep 1 + assert_nil Resque::Job.reserve(:delayed) + sleep 1 + assert_equal(DelayedJob, Resque::Job.reserve(:delayed).payload_class) + end + + test "delayed unique jobs modify args in place" do + args = { :delay_until => Time.new + 3600, :_id => 'unique'} + Resque.enqueue(DelayedJob, args) + assert_nil(Resque.peek(:delayed)) + args[:delay_until] = Time.new - 1 + Resque.enqueue(DelayedJob, args) + assert_equal(2, Resque::Job.reserve(:delayed).args[0].keys.count) + end + + test "delayed attribute is ignored when bypassing queues" do + Resque.bypass_queues = true + args = { :delay_until => Time.new+20} + foo = Resque.enqueue(DelayedJob, args) + assert(0, Resque.size(:delayed)) + assert(args[:delay_until] > Time.new) + assert(foo =~ /^delayed job executing/) + Resque.bypass_queues = false + end + + test "other queues are not affected" do + args = { :delay_until => Time.new+10} + assert OtherUnique.instance_variable_get :@delayed_jobs + Resque.enqueue(OtherUnique, args) + job = Resque::Job.reserve(:unique2) + assert_equal(1, job.args[0].keys.length) + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index c2e1b8222..e3645d268 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -100,5 +100,18 @@ def self.perform(data) class OtherUnique @queue = :unique2 @unique_jobs = true + @delayed_jobs = true end +class DelayedJob + @queue = :delayed + @delayed_jobs = true + @unique_jobs = true + + def self.perform(data) + "delayed job executing #{data.inspect}" + end + +end + + From e0390194ba9ec0cd39cca64d5fe8b8a46336b5ba Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 5 Oct 2010 11:37:20 -0400 Subject: [PATCH 32/59] changed rg to use patch instead of rg command line, changed failed to always return an array --- Rakefile | 3 +- lib/resque.rb | 2 +- lib/resque/failure/redis.rb | 2 +- lib/resque/server/views/stats.erb | 14 +++++++++ lib/resque/version.rb | 2 +- test/test_helper.rb | 47 +++++++++++++++++++++++++++++++ test/worker_test.rb | 4 +-- 7 files changed, 68 insertions(+), 6 deletions(-) diff --git a/Rakefile b/Rakefile index faa09d68e..cf8a74c17 100644 --- a/Rakefile +++ b/Rakefile @@ -21,7 +21,8 @@ desc "Run the test suite" task :test do rg = command?(:rg) Dir['test/**/*_test.rb'].each do |f| - rg ? sh("rg #{f}") : ruby(f) + #rg ? sh("rg #{f}") : ruby(f) + ruby(f) end end diff --git a/lib/resque.rb b/lib/resque.rb index 7f7d676ab..03c068a54 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -74,7 +74,7 @@ def mongo_workers end def mongo_stats - mongo['resque.stats'] + mongo['resque.metrics'] end def mongo_failures diff --git a/lib/resque/failure/redis.rb b/lib/resque/failure/redis.rb index b1dd5c77f..7b0f6c371 100644 --- a/lib/resque/failure/redis.rb +++ b/lib/resque/failure/redis.rb @@ -22,7 +22,7 @@ def self.count def self.all(start = 0, count = 1) all_failures = Resque.mongo_failures.find().sort([:natural, :desc]).skip(start).limit(count).to_a - all_failures.size == 1 ? all_failures.first : all_failures + # all_failures.size == 1 ? all_failures.first : all_failures end def self.clear diff --git a/lib/resque/server/views/stats.erb b/lib/resque/server/views/stats.erb index df3c945d0..f2b2cbd31 100644 --- a/lib/resque/server/views/stats.erb +++ b/lib/resque/server/views/stats.erb @@ -24,6 +24,20 @@

<%= resque.to_s %>

Class
"><%= queue %><%= resque.size queue %><%= resque.size queue.to_sym %>
+ <% resque.mongo_stats.find.to_a.each do |hash| %> + + + + + <% end %> +
+ <%= hash['stat'] %> + + <%= hash['value'] %> +
+ +

Mongo Database Health

+ <% resque.mongo.stats.each_pair do |key, value| %>
diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 7c5357662..0ff22a0cc 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.11.0' + Version = VERSION = '1.11.1' end diff --git a/test/test_helper.rb b/test/test_helper.rb index e3645d268..2913cf570 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -114,4 +114,51 @@ def self.perform(data) end +#some redgreen fun +# -*- coding: utf-8 -*- +begin + require 'redgreen' + module Test + module Unit + module UI + module Console + class TestRunner + def test_started(name) + @individual_test_start_time = Time.now + output_single(name + ": ", VERBOSE) + end + + def test_finished(name) + elapsed_test_time = Time.now - @individual_test_start_time + char_to_output = elapsed_test_time > 1 ? "☻" : "." + output_single(char_to_output, PROGRESS_ONLY) unless (@already_outputted) + nl(VERBOSE) + @already_outputted = false + end + end + end + end + end + end + + # -*- coding: utf-8 -*- + class Test::Unit::UI::Console::RedGreenTestRunner < Test::Unit::UI::Console::TestRunner + def output_single(something, level=NORMAL) + return unless (output?(level)) + something = case something + when '.' then Color.green('.') + when '☻' then Color.green('☻') + when 'F' then Color.red("F") + when 'E' then Color.yellow("E") + when '+' then Color.green('+') + else something + end + @io.write(something) + @io.flush + end + end +rescue LoadError + puts "consider gem install redgreen" +end + diff --git a/test/worker_test.rb b/test/worker_test.rb index 3016b334d..d2e7c11d1 100644 --- a/test/worker_test.rb +++ b/test/worker_test.rb @@ -19,8 +19,8 @@ test "failed jobs report exception and message" do Resque::Job.create(:jobs, BadJobWithSyntaxError) @worker.work(0) - assert_equal('SyntaxError', Resque::Failure.all['exception']) - assert_equal('Extra Bad job!', Resque::Failure.all['error']) + assert_equal('SyntaxError', Resque::Failure.all.first['exception']) + assert_equal('Extra Bad job!', Resque::Failure.all.first['error']) end test "fails uncompleted jobs on exit" do From b23d83427455cf8dd77039dcf176226c206d4fc9 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 5 Oct 2010 12:12:29 -0400 Subject: [PATCH 33/59] added 3 size queries for delayed jobs, made delayable queues initialize from stats on resque startup --- lib/resque.rb | 24 +++++++++++++++++------- test/resque_test.rb | 19 ++++++++++++++++++- test/test_helper.rb | 4 +++- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index 03c068a54..bbc842b71 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -48,7 +48,7 @@ def mongo=(server) end queuedb ||= 'resque' @mongo = conn.db queuedb - add_indexes + initialize_mongo end # Returns the current Mongo connection. If none has been created, will @@ -64,9 +64,11 @@ def mongo_db=(db) end - def add_indexes + def initialize_mongo mongo_workers.create_index :worker mongo_stats.create_index :stat + delay_allowed = mongo_stats.find_one({ :stat => 'Delayable Queues'}, { :fields => ['value']}) + @delay_allowed = delay_allowed['value'] if delay_allowed end def mongo_workers @@ -144,6 +146,7 @@ def allows_delayed_jobs(klass) def enable_delay(queue) @delay_allowed << queue unless @delay_allowed.include? queue + mongo_stats.update({:stat => 'Delayable Queues'}, { '$set' => { 'value' => @delay_allowed}}, { :upsert => true}) end # @@ -176,17 +179,24 @@ def pop(queue) # Returns an integer representing the size of a queue. # Queue name should be a string. - def size(queue) - + def size(queue) + mongo[queue].count + end + + def delayed_size(queue) if @delay_allowed.include? queue - mongo[queue].find({'delay_until' => { '$not' => { '$gt' => Time.new}}}).count + mongo[queue].find({'delay_until' => { '$gt' => Time.new}}).count else mongo[queue].count end end - def raw_size(queue) - mongo[queue].count + def ready_size(queue) + if @delay_allowed.include? queue + mongo[queue].find({'delay_until' => { '$not' => { '$gt' => Time.new}}}).count + else + mongo[queue].count + end end diff --git a/test/resque_test.rb b/test/resque_test.rb index 352000dfe..8a9103ca9 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -294,9 +294,10 @@ def pop_no_id(queue) assert_equal(1, job.args[0].keys.length) assert_equal(args[:delay_until].to_i, job.args[0]["delay_until"].to_i) args[:delay_until] = Time.new + 2 + assert_equal(0, Resque.delayed_size(:delayed)) Resque.enqueue(DelayedJob, args) - assert_equal(0, Resque.size(:delayed)) + assert_equal(1, Resque.delayed_size(:delayed)) assert_nil Resque.peek(:delayed) assert_nil Resque::Job.reserve(:delayed) sleep 1 @@ -331,4 +332,20 @@ def pop_no_id(queue) job = Resque::Job.reserve(:unique2) assert_equal(1, job.args[0].keys.length) end + + test "can enqueue normal jobs in a delayed queue" do + args = { :delay_until => Time.new + 3600} + Resque.enqueue(DelayedJob, args) + Resque.enqueue(DelayedJob, args) + Resque.enqueue(DelayedJob, args) + assert_equal(3, Resque.size(:delayed)) + assert_equal(3, Resque.delayed_size(:delayed)) + assert_equal(0, Resque.ready_size(:delayed)) + Resque.enqueue(NonDelayedJob, args) + Resque.enqueue(NonDelayedJob, args) + Resque.enqueue(DelayedJob, args) + assert_equal(6, Resque.size(:delayed)) + assert_equal(2, Resque.ready_size(:delayed)) + assert_equal(4, Resque.delayed_size(:delayed)) + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 2913cf570..5921ac4fa 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -107,11 +107,13 @@ class DelayedJob @queue = :delayed @delayed_jobs = true @unique_jobs = true - def self.perform(data) "delayed job executing #{data.inspect}" end +end +class NonDelayedJob + @queue = :delayed end #some redgreen fun From 468ba04c343762a3ba905084206d3f693bb8f159 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 5 Oct 2010 17:41:13 -0400 Subject: [PATCH 34/59] updates server app for new delayed structure, better support for mongoisms --- lib/resque.rb | 35 +++++++++--- lib/resque/server.rb | 83 +++++++++++++++++++--------- lib/resque/server/public/style.css | 7 ++- lib/resque/server/views/key_sets.erb | 8 +-- lib/resque/server/views/queues.erb | 61 ++++++++++++-------- lib/resque/server/views/stats.erb | 6 +- 6 files changed, 133 insertions(+), 67 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index bbc842b71..ae5ca35a2 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -68,7 +68,7 @@ def initialize_mongo mongo_workers.create_index :worker mongo_stats.create_index :stat delay_allowed = mongo_stats.find_one({ :stat => 'Delayable Queues'}, { :fields => ['value']}) - @delay_allowed = delay_allowed['value'] if delay_allowed + @delay_allowed = delay_allowed['value'].map{ |queue| queue.to_sym} if delay_allowed end def mongo_workers @@ -144,9 +144,15 @@ def allows_delayed_jobs(klass) (klass.respond_to?(:delayed_jobs) and klass.delayed_jobs) end + def queue_allows_delayed(queue) + @delay_allowed.include? queue + end + def enable_delay(queue) - @delay_allowed << queue unless @delay_allowed.include? queue - mongo_stats.update({:stat => 'Delayable Queues'}, { '$set' => { 'value' => @delay_allowed}}, { :upsert => true}) + unless @delay_allowed.include? queue + @delay_allowed << queue + mongo_stats.update({:stat => 'Delayable Queues'}, { '$addToSet' => { 'value' => queue}}, { :upsert => true}) + end end # @@ -208,18 +214,29 @@ def ready_size(queue) # # To get the 3rd page of a 30 item, paginatied list one would use: # Resque.peek('my_list', 59, 30) - def peek(queue, start = 0, count = 1) - list_range(queue, start, count) + def peek(queue, start = 0, count = 1, mode = :ready) + list_range(queue, start, count, mode) end # Does the dirty work of fetching a range of items from a Redis list # and converting them into Ruby objects. - def list_range(key, start = 0, count = 1) + def list_range(key, start = 0, count = 1, mode = :ready) query = { } - if @delay_allowed.include? key - query['delay_until'] = { '$not' => { '$gt' => Time.new}} + sort = [] + if @delay_allowed.include?(key) + if mode == :ready + query['delay_until'] = { '$not' => { '$gt' => Time.new}} + elsif mode == :delayed + query['delay_until'] = { '$gt' => Time.new} + elsif mode == :delayed_sorted + query['delay_until'] = { '$gt' => Time.new} + sort << ['delay_until', 1] + elsif mode == :all_sorted + query = {} + sort << ['delay_until', 1] + end end - items = mongo[key].find(query, { :limit => count, :skip => start}).to_a.map{ |i| i} + items = mongo[key].find(query, { :limit => count, :skip => start, :sort => sort}).to_a.map{ |i| i} count > 1 ? items : items.first end diff --git a/lib/resque/server.rb b/lib/resque/server.rb index b3443fe0f..9718ee0a9 100644 --- a/lib/resque/server.rb +++ b/lib/resque/server.rb @@ -46,34 +46,12 @@ def tabs Resque::Server.tabs end - def redis_get_size(key) - case Resque.redis.type(key) - when 'none' - [] - when 'list' - Resque.redis.llen(key) - when 'set' - Resque.redis.scard(key) - when 'string' - Resque.redis.get(key).length - when 'zset' - Resque.redis.zcard(key) - end + def mongo_get_size(key) + Resque.mongo[key].count end - def redis_get_value_as_array(key, start=0) - case Resque.redis.type(key) - when 'none' - [] - when 'list' - Resque.redis.lrange(key, start, start + 20) - when 'set' - Resque.redis.smembers(key)[start..(start + 20)] - when 'string' - [Resque.redis.get(key)] - when 'zset' - Resque.redis.zrange(key, start, start + 20) - end + def mongo_get_value_as_array(key, start=0) + Resque.mongo[key].find({ }, { :skip => start, :limit => 20}).to_a end def show_args(args) @@ -125,6 +103,59 @@ def show(page, layout = true) end end + def processes_in(delay_until) + return 'Immediately' if delay_until.nil? + now = Time.now + time = distance_of_time_in_words(now, delay_until) + return "Immediately (#{time})" if now > delay_until + return time + end + + def distance_of_time_in_words(from_time, to_time = 0, include_seconds = true, options = {}) + from_time = from_time.to_time if from_time.respond_to?(:to_time) + to_time = to_time.to_time if to_time.respond_to?(:to_time) + distance_in_minutes = (((to_time - from_time).abs)/60).round + distance_in_seconds = ((to_time - from_time).abs).round + + ago = from_time > to_time ? ' ago' : '' + + + case distance_in_minutes + when 0..1 + return distance_in_minutes == 0 ? + "less than 1 minute" + ago : + "#{distance_in_minutes} minutes" + ago unless include_seconds + + case distance_in_seconds + when 0..4 then "less than 5 seconds" + ago + when 5..9 then "less than 10 seconds" + ago + when 10..19 then "less than 20 seconds" + ago + when 20..39 then "half a minute" + ago + when 40..59 then "less than 1 minute" + ago + else "1 minute" + ago + end + + when 2..44 then "#{distance_in_minutes} minutes" + ago + when 45..89 then "about 1 hour" + ago + when 90..1439 then "about #{(distance_in_minutes.to_f / 60.0).round} hours" + ago + when 1440..2529 then "about 1 day" + ago + when 2530..43199 then "about #{(distance_in_minutes.to_f / 1440.0).round} days" + ago + when 43200..86399 then "about 1 month" + ago + when 86400..525599 then "about #{(distance_in_minutes.to_f / 43200.0).round} months" + ago + else + distance_in_years = distance_in_minutes / 525600 + minute_offset_for_leap_year = (distance_in_years / 4) * 1440 + remainder = ((distance_in_minutes - minute_offset_for_leap_year) % 525600) + if remainder < 131400 + "about #{distance_in_years} years" + ago + elsif remainder < 394200 + "over #{distance_in_years} years" + ago + else + "almost #{distance_in_years} years" + ago + end + end + end + # to make things easier on ourselves get "/?" do redirect url(:overview) diff --git a/lib/resque/server/public/style.css b/lib/resque/server/public/style.css index b96528bea..156e3a95f 100644 --- a/lib/resque/server/public/style.css +++ b/lib/resque/server/public/style.css @@ -40,6 +40,11 @@ body { padding:0; margin:0; } #main table.jobs td.class { font-family:Monaco, "Courier New", monospace; font-size:90%; width:50%;} #main table.jobs td.args{ width:50%;} +#main table.delays td.class { font-family:Monaco, "Courier New", monospace; font-size:90%; width:20%;} +#main table.delays td.args{ width:40%;} +#main table.delays td.delay{ width:40%;} + + #main table.workers td.icon {width:1%; background:#efefef;text-align:center;} #main table.workers td.where { width:25%;} #main table.workers td.queues { width:35%;} @@ -78,4 +83,4 @@ body { padding:0; margin:0; } #main form {float:right; margin-top:-10px;} -#main .time a.toggle_format {text-decoration:none;} \ No newline at end of file +#main .time a.toggle_format {text-decoration:none;} diff --git a/lib/resque/server/views/key_sets.erb b/lib/resque/server/views/key_sets.erb index 138a2b1b9..b0b80565c 100644 --- a/lib/resque/server/views/key_sets.erb +++ b/lib/resque/server/views/key_sets.erb @@ -1,16 +1,16 @@ <% if key = params[:key] %>

- Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <%=size = redis_get_size(key) %> + Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <%=size = mongo_get_size(key) %>

-

Key "<%= key %>" is a <%= resque.redis.type key %>

+

Elements in Collection <%= key %>

- <% for row in redis_get_value_as_array(key, start) %> + <% for row in mongo_get_value_as_array(key, start) %> <% end %> diff --git a/lib/resque/server/views/queues.erb b/lib/resque/server/views/queues.erb index ae95fd06c..3140ebb1b 100644 --- a/lib/resque/server/views/queues.erb +++ b/lib/resque/server/views/queues.erb @@ -1,46 +1,59 @@ <% @subtabs = resque.queues unless partial? || params[:id].nil? %> <% if queue = params[:id] %> - -

Pending jobs on <%= queue %>

+

Jobs on <%= queue %>

" class='remove-queue'> -

Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <%=size = resque.size(queue.to_sym)%> jobs

- <% if size != resque.raw_size(queue.to_sym) %> -

Delayed Jobs: <%= resque.raw_size(queue.to_sym)%>

- <% end %> -
- <%= row %> + <%= row.inspect %>
- - - - - <% for job in (jobs = resque.peek(queue, start, 20)) %> - - - - + <% if !resque.queue_allows_delayed queue.to_sym %> +

Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <%=size = resque.size(queue.to_sym)%> jobs

ClassArgs
<%= job['class'] %><%=h job['args'].inspect %>
+ + + + + <% for job in (jobs = resque.peek(queue.to_sym, start, 20)) %> + + + + + <% end %> + <% else %> +

Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <%=size = resque.size(queue.to_sym)%> jobs

ClassArgs1
<%= job['class'] %><%=h job['args'].inspect %>
+ + + + + + <% for job in (jobs = resque.peek(queue.to_sym, start, 20, :all_sorted)) %> + + + + + + <% end %> <% end %> <% if jobs.empty? %> - - - + + + <% end %> -
ClassArgsProcesses In
<%= job['class'] %><%=h job['args'].inspect %><%=h processes_in(job['delay_until']) %>
There are no pending jobs in this queue
There are no pending jobs in this queue
- <%= partial :next_more, :start => start, :size => size %> -<% else %> +
+ <%= partial :next_more, :start => start, :size => size %> + <% else %>

Queues

The list below contains all the registered queues with the number of jobs currently in the queue. Select a queue from above to view all jobs currently pending on the queue.

- + + <% for queue in resque.queues.sort_by { |q| q.to_s } %> - + + <% end %> "> diff --git a/lib/resque/server/views/stats.erb b/lib/resque/server/views/stats.erb index f2b2cbd31..e9a3fa92c 100644 --- a/lib/resque/server/views/stats.erb +++ b/lib/resque/server/views/stats.erb @@ -2,7 +2,7 @@ <% if params[:key] %> -<%= partial resque.redis.type(params[:key]).eql?("string") ? :key_string : :key_sets %> +<%= partial :key_sets %> <% elsif params[:id] == "resque" %> @@ -24,13 +24,13 @@

<%= resque.to_s %>

NameJobsReady JobsDelayed Jobs
"><%= queue %><%= resque.size queue.to_sym %><%= resque.ready_size queue.to_sym %><%= resque.delayed_size(queue.to_sym) if resque.queue_allows_delayed(queue.to_sym) %>
- <% resque.mongo_stats.find.to_a.each do |hash| %> + <% resque.mongo_stats.find.to_a.each do |hash| %> <% end %> From 2637cb5d3c2f871a67d36fa6d63b4a4c5f5925c6 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Fri, 8 Oct 2010 15:21:08 -0400 Subject: [PATCH 35/59] made delayed queue test a bit more robust --- lib/resque.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index ae5ca35a2..05deeb1ae 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -47,7 +47,7 @@ def mongo=(server) conn = server end queuedb ||= 'resque' - @mongo = conn.db queuedb + @mongo = conn.db queuedb initialize_mongo end @@ -145,11 +145,11 @@ def allows_delayed_jobs(klass) end def queue_allows_delayed(queue) - @delay_allowed.include? queue + @delay_allowed.include?(queue.to_sym) || @delay_allowed.include?(queue.to_s) end def enable_delay(queue) - unless @delay_allowed.include? queue + unless queue_allows_delayed queue @delay_allowed << queue mongo_stats.update({:stat => 'Delayable Queues'}, { '$addToSet' => { 'value' => queue}}, { :upsert => true}) end @@ -174,7 +174,7 @@ def push(queue, item) # Returns a Ruby object. def pop(queue) query = { } - if @delay_allowed.include? queue + if queue_allows_delayed queue query['delay_until'] = { '$not' => { '$gt' => Time.new}} end item = mongo[queue].find_and_modify(:query => query, :sort => [:natural, :desc], :remove => true ) @@ -190,7 +190,7 @@ def size(queue) end def delayed_size(queue) - if @delay_allowed.include? queue + if queue_allows_delayed queue mongo[queue].find({'delay_until' => { '$gt' => Time.new}}).count else mongo[queue].count @@ -198,7 +198,7 @@ def delayed_size(queue) end def ready_size(queue) - if @delay_allowed.include? queue + if queue_allows_delayed queue mongo[queue].find({'delay_until' => { '$not' => { '$gt' => Time.new}}}).count else mongo[queue].count @@ -223,7 +223,7 @@ def peek(queue, start = 0, count = 1, mode = :ready) def list_range(key, start = 0, count = 1, mode = :ready) query = { } sort = [] - if @delay_allowed.include?(key) + if queue_allows_delayed(key) if mode == :ready query['delay_until'] = { '$not' => { '$gt' => Time.new}} elsif mode == :delayed From a48aeaa8863a00075ff127c78f74bae0fb78e7e8 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 27 Oct 2010 15:40:39 -0400 Subject: [PATCH 36/59] Remove sorting in pop operation for speed. Update to version 1.1 in preparation for publishing. --- lib/resque.rb | 6 +++++- lib/resque/version.rb | 2 +- resque-igo.gemspec | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index 05deeb1ae..d25b3ccfc 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -63,6 +63,9 @@ def mongo_db=(db) mongo.conn.db = db end + def mongo? + return @mongo + end def initialize_mongo mongo_workers.create_index :worker @@ -177,7 +180,8 @@ def pop(queue) if queue_allows_delayed queue query['delay_until'] = { '$not' => { '$gt' => Time.new}} end - item = mongo[queue].find_and_modify(:query => query, :sort => [:natural, :desc], :remove => true ) + #sorting will result in significant performance penalties for large queues, you have been warned. + item = mongo[queue].find_and_modify(:query => query, :remove => true ) rescue Mongo::OperationFailure => e return nil if e.message =~ /No matching object/ raise e diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 0ff22a0cc..9438abcfd 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.11.1' + Version = VERSION = '1.1' end diff --git a/resque-igo.gemspec b/resque-igo.gemspec index b2830987c..a8c9e105b 100644 --- a/resque-igo.gemspec +++ b/resque-igo.gemspec @@ -6,8 +6,8 @@ Gem::Specification.new do |s| s.version = Resque::Version s.date = Time.now.strftime('%Y-%m-%d') s.summary = "Resque-igo is a mongo-backed queueing system" - s.homepage = "http://github.com/naginata/resque-mongo" - s.email = "naginata@gmail.com" + s.homepage = "http://github.com/mediocretes/resque-mongo" + s.email = "nacuff@igodigital.com" s.authors = [ "Nathan D Acuff" ] s.files = %w( README.markdown Rakefile LICENSE HISTORY.md ) @@ -30,7 +30,7 @@ Gem::Specification.new do |s| Resque is a Redis-backed Ruby library for creating background jobs, placing those jobs on multiple queues, and processing them later. -Resque-igo is the same thing, but for mongo. It would not exist without the work of defunkt and ctrochalakis on github. + Resque-igo is the same thing, but for mongo. It would not exist without the work of defunkt and ctrochalakis on github. Background jobs can be any Ruby class or module that responds to perform. Your existing classes can easily be converted to background From 88067dc4d0ea07a8dd92372bc4dd2136a9d7d0b6 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 27 Oct 2010 17:29:52 -0400 Subject: [PATCH 37/59] Removed ability for delayed and non delayed jobs to coexist in queues --- lib/resque.rb | 2 +- lib/resque/errors.rb | 3 +++ lib/resque/job.rb | 18 +++++++++++++++++- test/resque_test.rb | 34 ++++++++++++---------------------- test/test_helper.rb | 9 ++++++++- 5 files changed, 41 insertions(+), 25 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index d25b3ccfc..1bcb6fbcb 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -247,7 +247,7 @@ def list_range(key, start = 0, count = 1, mode = :ready) # Returns an array of all known Resque queues as strings. def queues names = mongo.collection_names - names.delete_if{ |name| name == 'system.indexes' || name =~ /resque\./ } + names.delete_if{ |name| name =~ /system./ || name =~ /resque\./ } end # Given a queue name, completely deletes the queue. diff --git a/lib/resque/errors.rb b/lib/resque/errors.rb index 1d0dd6801..be1b99390 100644 --- a/lib/resque/errors.rb +++ b/lib/resque/errors.rb @@ -7,4 +7,7 @@ class NoClassError < RuntimeError; end # Raised when a worker was killed while processing a job. class DirtyExit < RuntimeError; end + + #raised for bad delay/unique queue integrity + class QueueError < RuntimeError; end end diff --git a/lib/resque/job.rb b/lib/resque/job.rb index df42a5c8f..955fe663f 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -50,10 +50,26 @@ def self.create(queue, klass, *args) end item = { :class => klass.to_s, :args => args} + item[:_id] = args[0][:_id] if Resque.allows_unique_jobs(klass) && args[0].is_a?(Hash) && args[0].has_key?(:_id) item[:unique] = true if item[:_id] - item[:delay_until] = args[0][:delay_until] if Resque.allows_delayed_jobs(klass) && args[0].is_a?(Hash) && args[0].has_key?(:delay_until) + #are we trying to put a non-delayed job into a delayed queue? + if Resque.queue_allows_delayed(queue) + if Resque.allows_delayed_jobs(klass) + if args[0].is_a?(Hash) && args[0].has_key?(:delay_until) + item[:delay_until] = args[0][:delay_until] + else + raise QueueError.new 'trying to insert delayed job without delay_until' + end + else + raise QueueError.new 'trying to insert non-delayed job into delayed queue' + end + else + if Resque.allows_delayed_jobs(klass) + raise QueueError.new 'trying to insert a delayed job into a non-delayed queue' + end + end ret = Resque.push(queue, item) Plugin.after_enqueue_hooks(klass).each do |hook| diff --git a/test/resque_test.rb b/test/resque_test.rb index 8a9103ca9..323d699db 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -325,27 +325,17 @@ def pop_no_id(queue) Resque.bypass_queues = false end - test "other queues are not affected" do - args = { :delay_until => Time.new+10} - assert OtherUnique.instance_variable_get :@delayed_jobs - Resque.enqueue(OtherUnique, args) - job = Resque::Job.reserve(:unique2) - assert_equal(1, job.args[0].keys.length) - end - - test "can enqueue normal jobs in a delayed queue" do - args = { :delay_until => Time.new + 3600} - Resque.enqueue(DelayedJob, args) - Resque.enqueue(DelayedJob, args) - Resque.enqueue(DelayedJob, args) - assert_equal(3, Resque.size(:delayed)) - assert_equal(3, Resque.delayed_size(:delayed)) - assert_equal(0, Resque.ready_size(:delayed)) - Resque.enqueue(NonDelayedJob, args) - Resque.enqueue(NonDelayedJob, args) - Resque.enqueue(DelayedJob, args) - assert_equal(6, Resque.size(:delayed)) - assert_equal(2, Resque.ready_size(:delayed)) - assert_equal(4, Resque.delayed_size(:delayed)) + test "mixing delay and non-delay is bad" do + dargs = { :delay_until => Time.new + 3600} + + #non-delay into delay + assert_raise(Resque::QueueError) do + Resque.enqueue(NonDelayedJob, dargs) + end + + #delay into non-delay + assert_raise(Resque::QueueError) do + Resque.enqueue(MistargetedDelayedJob, dargs) + end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 5921ac4fa..c637e26f8 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -100,7 +100,6 @@ def self.perform(data) class OtherUnique @queue = :unique2 @unique_jobs = true - @delayed_jobs = true end class DelayedJob @@ -112,6 +111,14 @@ def self.perform(data) end end +class MistargetedDelayedJob + @queue = :unique + @delayed_jobs = true + def self.perform(data) + " mistargeteddelayed job executing #{data.inspect}" + end +end + class NonDelayedJob @queue = :delayed end From bb97dbc78019d797f7db82131402858beffe08ee Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Thu, 28 Oct 2010 19:10:11 -0400 Subject: [PATCH 38/59] failure backend for mongo that just might work --- lib/resque/failure/mongo.rb | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 lib/resque/failure/mongo.rb diff --git a/lib/resque/failure/mongo.rb b/lib/resque/failure/mongo.rb new file mode 100644 index 000000000..818812781 --- /dev/null +++ b/lib/resque/failure/mongo.rb @@ -0,0 +1,40 @@ +module Resque + module Failure + # A Failure backend that stores exceptions in Mongo. Very simple but + # works out of the box, along with support in the Resque web app. + class Mongo < Base + def save + data = { + :failed_at => Time.now.strftime("%Y/%m/%d %H:%M:%S"), + :payload => payload, + :exception => exception.class.to_s, + :error => exception.to_s, + :backtrace => Array(exception.backtrace), + :worker => worker.to_s, + :queue => queue + } + Resque.mongo_failures << data + end + + def self.count + Resque.mongo_failures.count + end + + def self.all(start = 0, count = 1) + all_failures = Resque.mongo_failures.find().skip(start).limit(count).to_a + # all_failures.size == 1 ? all_failures.first : all_failures + end + + def self.clear + Resque.mongo_failures.remove + end + + def self.requeue(index) + item = all(index) + item['retried_at'] = Time.now.strftime("%Y/%m/%d %H:%M:%S") + Resque.mongo_failures.update({ :_id => item['_id']}, item) + Job.create(item['queue'], item['payload']['class'], *item['payload']['args']) + end + end + end +end From e05bc1c3825470b649627aed84a2f790eb9d544e Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Thu, 28 Oct 2010 19:10:48 -0400 Subject: [PATCH 39/59] bump version --- lib/resque/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 9438abcfd..9b55ecc5c 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.1' + Version = VERSION = '1.1.1' end From 2642eac6de7231c20a17c702cf216ee3e7307b78 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Thu, 28 Oct 2010 19:14:09 -0400 Subject: [PATCH 40/59] changed redis to mogno --- lib/resque/failure.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/resque/failure.rb b/lib/resque/failure.rb index 7b4d570fb..0d547f7ee 100644 --- a/lib/resque/failure.rb +++ b/lib/resque/failure.rb @@ -32,8 +32,8 @@ def self.backend=(backend) # back to `Resque::Failure::Redis` def self.backend return @backend if @backend - require 'resque/failure/redis' - @backend = Failure::Redis + require 'resque/failure/mongo' + @backend = Failure::Mongo end # Returns the int count of how many failures we have seen. From d93fa6295b88ea443e3b8641d4879fad5c35f5b5 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Thu, 28 Oct 2010 19:29:05 -0400 Subject: [PATCH 41/59] more failure fixes. sorry for the spam, this is hard to test --- lib/resque/failure/mongo.rb | 3 ++- lib/resque/version.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/resque/failure/mongo.rb b/lib/resque/failure/mongo.rb index 818812781..18bb6ab35 100644 --- a/lib/resque/failure/mongo.rb +++ b/lib/resque/failure/mongo.rb @@ -21,7 +21,8 @@ def self.count end def self.all(start = 0, count = 1) - all_failures = Resque.mongo_failures.find().skip(start).limit(count).to_a + + all_failures = Resque.mongo_failures.find().skip(start.to_i).limit(count.to_i).to_a # all_failures.size == 1 ? all_failures.first : all_failures end diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 9b55ecc5c..d0d30862a 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.1.1' + Version = VERSION = '1.1.2' end From b6bc76d61ee497618adee721e19a2283e9a5d836 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Thu, 28 Oct 2010 19:46:01 -0400 Subject: [PATCH 42/59] fix for failure/all issue --- lib/resque/failure/mongo.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque/failure/mongo.rb b/lib/resque/failure/mongo.rb index 18bb6ab35..ea32b8620 100644 --- a/lib/resque/failure/mongo.rb +++ b/lib/resque/failure/mongo.rb @@ -23,7 +23,7 @@ def self.count def self.all(start = 0, count = 1) all_failures = Resque.mongo_failures.find().skip(start.to_i).limit(count.to_i).to_a - # all_failures.size == 1 ? all_failures.first : all_failures + all_failures.size == 1 ? all_failures.first : all_failures end def self.clear From a79da22a6603409a369d962f3dafaf1440e66a0a Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Thu, 28 Oct 2010 19:51:33 -0400 Subject: [PATCH 43/59] version bump --- lib/resque/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque/version.rb b/lib/resque/version.rb index d0d30862a..9b3cf7089 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.1.2' + Version = VERSION = '1.1.3' end From 34e5b2252c500fa2680426d9909421ee9ccffde5 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 3 Nov 2010 11:59:31 -0400 Subject: [PATCH 44/59] added timestamp to all jobs --- lib/resque.rb | 1 + lib/resque/failure/mongo.rb | 1 - lib/resque/server.rb | 4 ++++ lib/resque/server/views/queues.erb | 6 +++++- lib/resque/version.rb | 2 +- resque-igo-1.1.4.gem | Bin 0 -> 72192 bytes test/resque_test.rb | 14 +++++++------- test/worker_test.rb | 6 ++++-- 8 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 resque-igo-1.1.4.gem diff --git a/lib/resque.rb b/lib/resque.rb index 1bcb6fbcb..527748160 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -165,6 +165,7 @@ def enable_delay(queue) # Pushes a job onto a queue. Queue name should be a string and the # item should be any JSON-able Ruby object. def push(queue, item) + item[:resque_enqueue_timestamp] = Time.now if item[:unique] mongo[queue].update({'_id' => item[:_id]}, item, { :upsert => true}) else diff --git a/lib/resque/failure/mongo.rb b/lib/resque/failure/mongo.rb index ea32b8620..967a951a0 100644 --- a/lib/resque/failure/mongo.rb +++ b/lib/resque/failure/mongo.rb @@ -21,7 +21,6 @@ def self.count end def self.all(start = 0, count = 1) - all_failures = Resque.mongo_failures.find().skip(start.to_i).limit(count.to_i).to_a all_failures.size == 1 ? all_failures.first : all_failures end diff --git a/lib/resque/server.rb b/lib/resque/server.rb index 9718ee0a9..f8023b1e6 100644 --- a/lib/resque/server.rb +++ b/lib/resque/server.rb @@ -110,6 +110,10 @@ def processes_in(delay_until) return "Immediately (#{time})" if now > delay_until return time end + + def enqueued_at(resque_enqueue_timestamp) + + end def distance_of_time_in_words(from_time, to_time = 0, include_seconds = true, options = {}) from_time = from_time.to_time if from_time.respond_to?(:to_time) diff --git a/lib/resque/server/views/queues.erb b/lib/resque/server/views/queues.erb index 3140ebb1b..92cfeba10 100644 --- a/lib/resque/server/views/queues.erb +++ b/lib/resque/server/views/queues.erb @@ -10,11 +10,13 @@ + <% for job in (jobs = resque.peek(queue.to_sym, start, 20)) %> + <% end %> <% else %> @@ -22,14 +24,16 @@ + <% for job in (jobs = resque.peek(queue.to_sym, start, 20, :all_sorted)) %> + - + <% end %> <% end %> <% if jobs.empty? %> diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 9b3cf7089..c59d4a84d 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.1.3' + Version = VERSION = '1.1.4' end diff --git a/resque-igo-1.1.4.gem b/resque-igo-1.1.4.gem new file mode 100644 index 0000000000000000000000000000000000000000..7894cc9041db1c768953d68068f0c36bf6a48996 GIT binary patch literal 72192 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

J!kYl|U^w^(* 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 S+CBbB>mLOELE!&00{;b4Dc6Dk literal 0 HcmV?d00001 diff --git a/test/resque_test.rb b/test/resque_test.rb index 323d699db..8a41b6ec5 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -141,27 +141,27 @@ def pop_no_id(queue) test "can pull items off a queue" do - assert_equal({ 'name' => 'chris' }, pop_no_id(:people)) - assert_equal({ 'name' => 'bob' }, pop_no_id(:people)) - assert_equal({ 'name' => 'mark' }, pop_no_id(:people)) + assert_equal('chris', pop_no_id(:people)['name']) + assert_equal('bob', pop_no_id(:people)['name']) + assert_equal('mark', pop_no_id(:people)['name']) assert_equal nil, Resque.pop(:people) end test "knows how big a queue is" do assert_equal 3, Resque.size(:people) - assert_equal({ 'name' => 'chris' }, pop_no_id(:people)) + assert_equal('chris', pop_no_id(:people)['name']) assert_equal 2, Resque.size(:people) - assert_equal({ 'name' => 'bob' }, pop_no_id(:people)) - assert_equal({ 'name' => 'mark' }, pop_no_id(:people)) + assert_equal('bob', pop_no_id(:people)['name']) + assert_equal('mark', pop_no_id(:people)['name']) assert_equal 0, Resque.size(:people) end test "can peek at a queue" do peek = Resque.peek(:people) peek.delete "_id" - assert_equal({ 'name' => 'chris' }, peek) + assert_equal('chris', peek['name']) assert_equal 3, Resque.size(:people) end diff --git a/test/worker_test.rb b/test/worker_test.rb index d2e7c11d1..20020ef05 100644 --- a/test/worker_test.rb +++ b/test/worker_test.rb @@ -19,8 +19,9 @@ test "failed jobs report exception and message" do Resque::Job.create(:jobs, BadJobWithSyntaxError) @worker.work(0) - assert_equal('SyntaxError', Resque::Failure.all.first['exception']) - assert_equal('Extra Bad job!', Resque::Failure.all.first['error']) + failure = Resque::Failure.all.is_a?(Array) ? Resque::Failure.all.first : Resque::Failure.all + assert_equal('SyntaxError', failure['exception']) + assert_equal('Extra Bad job!', failure['error']) end test "fails uncompleted jobs on exit" do @@ -142,6 +143,7 @@ @worker.work(0) do task = @worker.job task['payload'].delete "_id" + task['payload'].delete "resque_enqueue_timestamp" assert_equal({"args"=>[20, "/tmp"], "class"=>"SomeJob"}, task['payload']) assert task['run_at'] assert_equal 'jobs', task['queue'].to_s From 235ab042793013162ec563146ce22654bd882d81 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 3 Nov 2010 12:05:25 -0400 Subject: [PATCH 45/59] how did my .gem get in there? --- resque-igo.gemspec | 47 ---------------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 resque-igo.gemspec diff --git a/resque-igo.gemspec b/resque-igo.gemspec deleted file mode 100644 index a8c9e105b..000000000 --- a/resque-igo.gemspec +++ /dev/null @@ -1,47 +0,0 @@ -$LOAD_PATH.unshift 'lib' -require 'resque/version' - -Gem::Specification.new do |s| - s.name = "resque-igo" - s.version = Resque::Version - s.date = Time.now.strftime('%Y-%m-%d') - s.summary = "Resque-igo is a mongo-backed queueing system" - s.homepage = "http://github.com/mediocretes/resque-mongo" - s.email = "nacuff@igodigital.com" - s.authors = [ "Nathan D Acuff" ] - - s.files = %w( README.markdown Rakefile LICENSE HISTORY.md ) - s.files += Dir.glob("lib/**/*") - s.files += Dir.glob("bin/**/*") - s.files += Dir.glob("man/**/*") - s.files += Dir.glob("test/**/*") - s.files += Dir.glob("tasks/**/*") - s.executables = [ "resque", "resque-web" ] - - s.extra_rdoc_files = [ "LICENSE", "README.markdown" ] - s.rdoc_options = ["--charset=UTF-8"] - - s.add_dependency "vegas", "~> 0.1.2" - s.add_dependency "sinatra", ">= 0.9.2" - s.add_dependency "json", "~> 1.4.6" - s.add_dependency "mongo", ">= 1.0.7" - - s.description = < Date: Wed, 3 Nov 2010 12:05:51 -0400 Subject: [PATCH 46/59] Revert "how did my .gem get in there?" This reverts commit 235ab042793013162ec563146ce22654bd882d81. --- resque-igo.gemspec | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 resque-igo.gemspec diff --git a/resque-igo.gemspec b/resque-igo.gemspec new file mode 100644 index 000000000..a8c9e105b --- /dev/null +++ b/resque-igo.gemspec @@ -0,0 +1,47 @@ +$LOAD_PATH.unshift 'lib' +require 'resque/version' + +Gem::Specification.new do |s| + s.name = "resque-igo" + s.version = Resque::Version + s.date = Time.now.strftime('%Y-%m-%d') + s.summary = "Resque-igo is a mongo-backed queueing system" + s.homepage = "http://github.com/mediocretes/resque-mongo" + s.email = "nacuff@igodigital.com" + s.authors = [ "Nathan D Acuff" ] + + s.files = %w( README.markdown Rakefile LICENSE HISTORY.md ) + s.files += Dir.glob("lib/**/*") + s.files += Dir.glob("bin/**/*") + s.files += Dir.glob("man/**/*") + s.files += Dir.glob("test/**/*") + s.files += Dir.glob("tasks/**/*") + s.executables = [ "resque", "resque-web" ] + + s.extra_rdoc_files = [ "LICENSE", "README.markdown" ] + s.rdoc_options = ["--charset=UTF-8"] + + s.add_dependency "vegas", "~> 0.1.2" + s.add_dependency "sinatra", ">= 0.9.2" + s.add_dependency "json", "~> 1.4.6" + s.add_dependency "mongo", ">= 1.0.7" + + s.description = < Date: Wed, 3 Nov 2010 12:06:22 -0400 Subject: [PATCH 47/59] removed gem for real --- resque-igo-1.1.4.gem | Bin 72192 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 resque-igo-1.1.4.gem diff --git a/resque-igo-1.1.4.gem b/resque-igo-1.1.4.gem deleted file mode 100644 index 7894cc9041db1c768953d68068f0c36bf6a48996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72192 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

J!kYl|U^w^(* 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 S+CBbB>mLOELE!&00{;b4Dc6Dk From d9878626c72fbdeba26f362b824d1b7218b32ed3 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 3 Nov 2010 12:12:15 -0400 Subject: [PATCH 48/59] fix enqueued at/processes in issues --- lib/resque/server.rb | 5 ++++- lib/resque/server/views/queues.erb | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/resque/server.rb b/lib/resque/server.rb index f8023b1e6..b1b9da35d 100644 --- a/lib/resque/server.rb +++ b/lib/resque/server.rb @@ -112,7 +112,10 @@ def processes_in(delay_until) end def enqueued_at(resque_enqueue_timestamp) - + return 'Unknown' if delay_until.nil? + now = Time.now + time = distance_of_time_in_words(now, resque_enqueue_timestamp) + return "time" end def distance_of_time_in_words(from_time, to_time = 0, include_seconds = true, options = {}) diff --git a/lib/resque/server/views/queues.erb b/lib/resque/server/views/queues.erb index 92cfeba10..2ae97be2d 100644 --- a/lib/resque/server/views/queues.erb +++ b/lib/resque/server/views/queues.erb @@ -16,7 +16,7 @@

- + <% end %> <% else %> From b43ff774f8342c4f63a9f8c287f22285f745b005 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 3 Nov 2010 12:14:38 -0400 Subject: [PATCH 49/59] bad variable name --- lib/resque/server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque/server.rb b/lib/resque/server.rb index b1b9da35d..8f566bbfd 100644 --- a/lib/resque/server.rb +++ b/lib/resque/server.rb @@ -112,7 +112,7 @@ def processes_in(delay_until) end def enqueued_at(resque_enqueue_timestamp) - return 'Unknown' if delay_until.nil? + return 'Unknown' if resque_enqueue_timestamp.nil? now = Time.now time = distance_of_time_in_words(now, resque_enqueue_timestamp) return "time" From a591f1faf3934eca202c6c934e6cb07297269d2f Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 3 Nov 2010 12:19:09 -0400 Subject: [PATCH 50/59] this time, I actually tested it, enqueue-at works and looks good now --- lib/resque/server.rb | 2 +- lib/resque/server/public/style.css | 6 ++++-- lib/resque/server/views/queues.erb | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/resque/server.rb b/lib/resque/server.rb index 8f566bbfd..c83c49ecc 100644 --- a/lib/resque/server.rb +++ b/lib/resque/server.rb @@ -115,7 +115,7 @@ def enqueued_at(resque_enqueue_timestamp) return 'Unknown' if resque_enqueue_timestamp.nil? now = Time.now time = distance_of_time_in_words(now, resque_enqueue_timestamp) - return "time" + return time end def distance_of_time_in_words(from_time, to_time = 0, include_seconds = true, options = {}) diff --git a/lib/resque/server/public/style.css b/lib/resque/server/public/style.css index 156e3a95f..6791e7a72 100644 --- a/lib/resque/server/public/style.css +++ b/lib/resque/server/public/style.css @@ -37,12 +37,14 @@ body { padding:0; margin:0; } #main table.queues tr.failure td { background:#ffecec; border-top:2px solid #d37474; font-size:90%; color:#d37474;} #main table.queues tr.failure td a{ color:#d37474;} -#main table.jobs td.class { font-family:Monaco, "Courier New", monospace; font-size:90%; width:50%;} +#main table.jobs td.class { font-family:Monaco, "Courier New", monospace; font-size:90%; width:30%;} #main table.jobs td.args{ width:50%;} +#main table.jobs td.enqueuedat{ width:20%;} #main table.delays td.class { font-family:Monaco, "Courier New", monospace; font-size:90%; width:20%;} #main table.delays td.args{ width:40%;} -#main table.delays td.delay{ width:40%;} +#main table.delays td.delay{ width:20%;} +#main table.delays td.enqueuedat{ width:20%;} #main table.workers td.icon {width:1%; background:#efefef;text-align:center;} diff --git a/lib/resque/server/views/queues.erb b/lib/resque/server/views/queues.erb index 2ae97be2d..fcf65bb19 100644 --- a/lib/resque/server/views/queues.erb +++ b/lib/resque/server/views/queues.erb @@ -16,7 +16,7 @@ - + <% end %> <% else %> From e09c2f6c1f88c948d456b6e81e6ab50a5d059418 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 3 Nov 2010 12:41:21 -0400 Subject: [PATCH 51/59] style cleanup --- lib/resque/server/public/style.css | 4 ++-- lib/resque/server/views/queues.erb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/resque/server/public/style.css b/lib/resque/server/public/style.css index 6791e7a72..1dde49245 100644 --- a/lib/resque/server/public/style.css +++ b/lib/resque/server/public/style.css @@ -38,11 +38,11 @@ body { padding:0; margin:0; } #main table.queues tr.failure td a{ color:#d37474;} #main table.jobs td.class { font-family:Monaco, "Courier New", monospace; font-size:90%; width:30%;} -#main table.jobs td.args{ width:50%;} +#main table.jobs td.args{ width:50%;word-break:break-word;} #main table.jobs td.enqueuedat{ width:20%;} #main table.delays td.class { font-family:Monaco, "Courier New", monospace; font-size:90%; width:20%;} -#main table.delays td.args{ width:40%;} +#main table.delays td.args{ width:40%;word-break:break-word;} #main table.delays td.delay{ width:20%;} #main table.delays td.enqueuedat{ width:20%;} diff --git a/lib/resque/server/views/queues.erb b/lib/resque/server/views/queues.erb index fcf65bb19..aa4a5cd65 100644 --- a/lib/resque/server/views/queues.erb +++ b/lib/resque/server/views/queues.erb @@ -9,7 +9,7 @@

Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <%=size = resque.size(queue.to_sym)%> jobs

<%= hash['stat'] %> - <%= hash['value'] %> + <%= hash['value'].inspect %>
Class Args1Enqueued At
<%= job['class'] %> <%=h job['args'].inspect %>
Class ArgsEnqueued At Processes In
<%= job['class'] %> <%=h job['args'].inspect %><%=h enqueued_at(job['resque_enqueue_timestamp']) %> <%=h processes_in(job['delay_until']) %>
<%= job['class'] %> <%=h job['args'].inspect %>><%=h enqueued_at(job['resque_enqueue_timestamp']) %>
<%= job['class'] %> <%=h job['args'].inspect %>><%=h enqueued_at(job['resque_enqueue_timestamp']) %><%=h enqueued_at(job['resque_enqueue_timestamp']) %>
- + <% for job in (jobs = resque.peek(queue.to_sym, start, 20)) %> From e7e91d006a19bb4264113ecabc103ae07bee1717 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 1 Dec 2010 17:09:40 -0500 Subject: [PATCH 52/59] add hydra feature --- lib/resque/job.rb | 4 ++++ lib/resque/version.rb | 2 +- test/resque_test.rb | 12 +++++++++++- test/test_helper.rb | 5 +++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/resque/job.rb b/lib/resque/job.rb index 955fe663f..c81b4d5b6 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -70,6 +70,10 @@ def self.create(queue, klass, *args) raise QueueError.new 'trying to insert a delayed job into a non-delayed queue' end end + + #is it a hydra job? + heads = klass.instance_variable_get(:@hydra) + queue = (queue.to_s + rand(heads).to_s).to_sym if heads ret = Resque.push(queue, item) Plugin.after_enqueue_hooks(klass).each do |hook| diff --git a/lib/resque/version.rb b/lib/resque/version.rb index c59d4a84d..9fc18869e 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.1.4' + Version = VERSION = '1.1.5' end diff --git a/test/resque_test.rb b/test/resque_test.rb index 8a41b6ec5..29783c623 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -319,7 +319,7 @@ def pop_no_id(queue) Resque.bypass_queues = true args = { :delay_until => Time.new+20} foo = Resque.enqueue(DelayedJob, args) - assert(0, Resque.size(:delayed)) + assert_equal(0, Resque.size(:delayed)) assert(args[:delay_until] > Time.new) assert(foo =~ /^delayed job executing/) Resque.bypass_queues = false @@ -338,4 +338,14 @@ def pop_no_id(queue) Resque.enqueue(MistargetedDelayedJob, dargs) end end + + test "hydra works" do + 20.times do + Resque.enqueue(HydraJob, { :one => 'one'}) + end + assert_equal(0, Resque.size(:hydra)) + assert_equal(20, Resque.size(:hydra1)+Resque.size(:hydra0)) + assert(0 != Resque.size(:hydra1)) + assert(0 != Resque.size(:hydra0)) + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index c637e26f8..f1add1ad8 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -123,6 +123,11 @@ class NonDelayedJob @queue = :delayed end +class HydraJob + @queue = :hydra + @hydra = 2 +end + #some redgreen fun # -*- coding: utf-8 -*- begin From ef8fea69c12429ca55e7ce6348cac9cc2c5713da Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Wed, 1 Dec 2010 17:25:57 -0500 Subject: [PATCH 53/59] gratuitous version bump --- lib/resque/version.rb | 2 +- resque-igo-1.12.1.gem | Bin 0 -> 72192 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 resque-igo-1.12.1.gem diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 9fc18869e..839c02fdd 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.1.5' + Version = VERSION = '1.12.1' end diff --git a/resque-igo-1.12.1.gem b/resque-igo-1.12.1.gem new file mode 100644 index 0000000000000000000000000000000000000000..49b9cdd609e6e21720327f734fb6472cdc354b74 GIT binary patch literal 72192 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

Xr$Us zG8tKzu?Aoxx6CZE433dEqimvqSL&dy$?LxkHs!67y7oGgy5mUE6|4#(IcY2H?v3A8 zTbh^qF*mnN$Lqi7MBy9rH!;hHJy3>ECo^6)48xSU>a&;AU@|O#+48n=*U!w9M&(9c!Z)qjA{H z$xh>fp))f&o(8$Peg5dHX6?GVz97cBDU!Q4`xEJs?O;wW*{3UgLBb{01Jq;-KIWDR zWmRug5y^ai%YgNf?4^l&+%?hmy?kS3LA2));~&We+lt_|PL6-m@bO=@{_BDNdf-3U G1OEeW`H6r4 literal 0 HcmV?d00001 From 1564e0755098594f2caeb82bb08847d208e82b97 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Fri, 3 Dec 2010 14:41:09 -0500 Subject: [PATCH 54/59] hydra now hashes ids for unique jobs --- lib/resque/job.rb | 8 +++++++- lib/resque/version.rb | 2 +- test/resque_test.rb | 10 ++++++++++ test/test_helper.rb | 6 ++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/resque/job.rb b/lib/resque/job.rb index c81b4d5b6..397db582c 100644 --- a/lib/resque/job.rb +++ b/lib/resque/job.rb @@ -73,7 +73,13 @@ def self.create(queue, klass, *args) #is it a hydra job? heads = klass.instance_variable_get(:@hydra) - queue = (queue.to_s + rand(heads).to_s).to_sym if heads + if heads + if item[:_id] + queue = (queue.to_s + (item[:_id].hash % heads).to_s).to_sym + else + queue = (queue.to_s + rand(heads).to_s).to_sym + end + end ret = Resque.push(queue, item) Plugin.after_enqueue_hooks(klass).each do |hook| diff --git a/lib/resque/version.rb b/lib/resque/version.rb index 839c02fdd..c10dd931b 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.12.1' + Version = VERSION = '1.12.2' end diff --git a/test/resque_test.rb b/test/resque_test.rb index 29783c623..e83621d28 100644 --- a/test/resque_test.rb +++ b/test/resque_test.rb @@ -348,4 +348,14 @@ def pop_no_id(queue) assert(0 != Resque.size(:hydra1)) assert(0 != Resque.size(:hydra0)) end + + test "hydra/unique hashes correctly" do + 20.times do + Resque.enqueue(UniqueHydraJob, {:_id => 'zomgz', :one => 'one'}) + end + # 'zomgz'.hash % 100 == 39 + assert_equal(1, Resque.size(:hydra39)) + Resque.enqueue(UniqueHydraJob, {:_id => '518', :one => 'one'}) + assert_equal(2, Resque.size(:hydra39)) + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index f1add1ad8..142b46341 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -128,6 +128,12 @@ class HydraJob @hydra = 2 end +class UniqueHydraJob + @queue = :hydra + @unique_jobs = true + @hydra = 100 +end + #some redgreen fun # -*- coding: utf-8 -*- begin From 78ced6dba413b32689b4e4b166fb856ca1f67af4 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Thu, 9 Dec 2010 16:11:35 -0500 Subject: [PATCH 55/59] resque queues now shows queue size --- bin/resque | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bin/resque b/bin/resque index 18008db97..0f36f39eb 100755 --- a/bin/resque +++ b/bin/resque @@ -1,6 +1,7 @@ #!/usr/bin/env ruby $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib' +require 'rubygems' require 'resque' def kill(worker) @@ -34,6 +35,12 @@ def list end end +def queues + Resque.queues.each do |queue| + puts"Queue #{queue}: #{Resque.size(queue)}" + end +end + if (i = ARGV.index('-r')) && ARGV[i+1] Resque.redis = ARGV[i+1] ARGV.delete_at(i) @@ -47,6 +54,8 @@ when 'remove' remove ARGV[1] when 'list' list +when 'queues' + queues else puts "Usage: resque [-r redis_host:redis_port] COMMAND [option]" puts @@ -54,4 +63,5 @@ else puts " remove WORKER Removes a worker" puts " kill WORKER Kills a worker" puts " list Lists known workers" + puts " queues checks queue depth" end From df776673cc539ade257f072d0f9891dd72ca279b Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Fri, 10 Dec 2010 15:02:00 -0500 Subject: [PATCH 56/59] fix issue on failure page with only one failure --- lib/resque/server/views/failed.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/resque/server/views/failed.erb b/lib/resque/server/views/failed.erb index 8333e7d2c..c4f316696 100644 --- a/lib/resque/server/views/failed.erb +++ b/lib/resque/server/views/failed.erb @@ -12,6 +12,7 @@

Showing <%=start%> to <%= start + 20 %> of <%= size = Resque::Failure.count %> jobs

    + <% failed = [failed] unless failed.is_a? Array %> <%for job in failed%> <% index += 1 %>
  • From f21730997edd489ce681d4a3aa6861de1a353a5a Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 14 Dec 2010 17:51:35 -0500 Subject: [PATCH 57/59] new pop sorting, should be more accurate and just as fast --- lib/resque.rb | 2 +- lib/resque/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/resque.rb b/lib/resque.rb index 527748160..73187bef0 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -182,7 +182,7 @@ def pop(queue) query['delay_until'] = { '$not' => { '$gt' => Time.new}} end #sorting will result in significant performance penalties for large queues, you have been warned. - item = mongo[queue].find_and_modify(:query => query, :remove => true ) + item = mongo[queue].find_and_modify(:query => query, :remove => true, :sort => [[:_id, :asc]] ) rescue Mongo::OperationFailure => e return nil if e.message =~ /No matching object/ raise e diff --git a/lib/resque/version.rb b/lib/resque/version.rb index c10dd931b..ab9148a2c 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.12.2' + Version = VERSION = '1.12.3' end From bd6b5ca261b11417d5535a6a4068143c3d648b8f Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 14 Dec 2010 18:14:39 -0500 Subject: [PATCH 58/59] roll back _id sort change, it's just not fast enough --- lib/resque.rb | 3 ++- lib/resque/version.rb | 2 +- resque-igo-1.12.1.gem | Bin 72192 -> 0 bytes 3 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 resque-igo-1.12.1.gem diff --git a/lib/resque.rb b/lib/resque.rb index 73187bef0..db7268323 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -182,7 +182,8 @@ def pop(queue) query['delay_until'] = { '$not' => { '$gt' => Time.new}} end #sorting will result in significant performance penalties for large queues, you have been warned. - item = mongo[queue].find_and_modify(:query => query, :remove => true, :sort => [[:_id, :asc]] ) + #this applies to _id, too. it'd be nice, but it won't work, so don't try it. + item = mongo[queue].find_and_modify(:query => query, :remove => true) #, :sort => [[:_id, :asc]] ) rescue Mongo::OperationFailure => e return nil if e.message =~ /No matching object/ raise e diff --git a/lib/resque/version.rb b/lib/resque/version.rb index ab9148a2c..c01f7da8e 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.12.3' + Version = VERSION = '1.12.4' end diff --git a/resque-igo-1.12.1.gem b/resque-igo-1.12.1.gem deleted file mode 100644 index 49b9cdd609e6e21720327f734fb6472cdc354b74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72192 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

    Xr$Us zG8tKzu?Aoxx6CZE433dEqimvqSL&dy$?LxkHs!67y7oGgy5mUE6|4#(IcY2H?v3A8 zTbh^qF*mnN$Lqi7MBy9rH!;hHJy3>ECo^6)48xSU>a&;AU@|O#+48n=*U!w9M&(9c!Z)qjA{H z$xh>fp))f&o(8$Peg5dHX6?GVz97cBDU!Q4`xEJs?O;wW*{3UgLBb{01Jq;-KIWDR zWmRug5y^ai%YgNf?4^l&+%?hmy?kS3LA2));~&We+lt_|PL6-m@bO=@{_BDNdf-3U G1OEeW`H6r4 From f11a644714e24214985dfada14cd636d32921952 Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 14 Dec 2010 19:35:33 -0500 Subject: [PATCH 59/59] Revert "roll back _id sort change, it's just not fast enough" This reverts commit bd6b5ca261b11417d5535a6a4068143c3d648b8f. --- lib/resque.rb | 3 +-- lib/resque/version.rb | 2 +- resque-igo-1.12.1.gem | Bin 0 -> 72192 bytes 3 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 resque-igo-1.12.1.gem diff --git a/lib/resque.rb b/lib/resque.rb index db7268323..73187bef0 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -182,8 +182,7 @@ def pop(queue) query['delay_until'] = { '$not' => { '$gt' => Time.new}} end #sorting will result in significant performance penalties for large queues, you have been warned. - #this applies to _id, too. it'd be nice, but it won't work, so don't try it. - item = mongo[queue].find_and_modify(:query => query, :remove => true) #, :sort => [[:_id, :asc]] ) + item = mongo[queue].find_and_modify(:query => query, :remove => true, :sort => [[:_id, :asc]] ) rescue Mongo::OperationFailure => e return nil if e.message =~ /No matching object/ raise e diff --git a/lib/resque/version.rb b/lib/resque/version.rb index c01f7da8e..ab9148a2c 100644 --- a/lib/resque/version.rb +++ b/lib/resque/version.rb @@ -1,3 +1,3 @@ module Resque - Version = VERSION = '1.12.4' + Version = VERSION = '1.12.3' end diff --git a/resque-igo-1.12.1.gem b/resque-igo-1.12.1.gem new file mode 100644 index 0000000000000000000000000000000000000000..49b9cdd609e6e21720327f734fb6472cdc354b74 GIT binary patch literal 72192 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

    Xr$Us zG8tKzu?Aoxx6CZE433dEqimvqSL&dy$?LxkHs!67y7oGgy5mUE6|4#(IcY2H?v3A8 zTbh^qF*mnN$Lqi7MBy9rH!;hHJy3>ECo^6)48xSU>a&;AU@|O#+48n=*U!w9M&(9c!Z)qjA{H z$xh>fp))f&o(8$Peg5dHX6?GVz97cBDU!Q4`xEJs?O;wW*{3UgLBb{01Jq;-KIWDR zWmRug5y^ai%YgNf?4^l&+%?hmy?kS3LA2));~&We+lt_|PL6-m@bO=@{_BDNdf-3U G1OEeW`H6r4 literal 0 HcmV?d00001

ClassArgs1Args Enqueued At