resque-pause 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ coverage/*
5
+ .rvmrc
6
+ .project
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in resque-pause.gemspec
4
+ gemspec
5
+
6
+ group :test, :development do
7
+ platforms :mri_18 do
8
+ gem "ruby-debug"
9
+ end
10
+
11
+ platforms :mri_19 do
12
+ gem "ruby-debug19", :require => 'ruby-debug' if RUBY_VERSION < "1.9.3"
13
+ end
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,73 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ resque-pause (0.0.2)
5
+ resque (>= 1.9.10)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ archive-tar-minitar (0.5.2)
11
+ columnize (0.3.3)
12
+ diff-lcs (1.1.2)
13
+ json_pure (1.4.6)
14
+ linecache (0.46)
15
+ rbx-require-relative (> 0.0.4)
16
+ linecache19 (0.5.12)
17
+ ruby_core_source (>= 0.1.4)
18
+ rack (1.3.0)
19
+ rack-test (0.6.0)
20
+ rack (>= 1.0)
21
+ rbx-require-relative (0.0.5)
22
+ redis (2.2.1)
23
+ redis-namespace (0.8.0)
24
+ redis (< 3.0.0)
25
+ resque (1.9.10)
26
+ json_pure (~> 1.4.0)
27
+ redis-namespace (~> 0.8.0)
28
+ sinatra (>= 0.9.2)
29
+ vegas (~> 0.1.2)
30
+ rspec (2.6.0)
31
+ rspec-core (~> 2.6.0)
32
+ rspec-expectations (~> 2.6.0)
33
+ rspec-mocks (~> 2.6.0)
34
+ rspec-core (2.6.4)
35
+ rspec-expectations (2.6.0)
36
+ diff-lcs (~> 1.1.2)
37
+ rspec-mocks (2.6.0)
38
+ ruby-debug (0.10.4)
39
+ columnize (>= 0.1)
40
+ ruby-debug-base (~> 0.10.4.0)
41
+ ruby-debug-base (0.10.4)
42
+ linecache (>= 0.3)
43
+ ruby-debug-base19 (0.11.25)
44
+ columnize (>= 0.3.1)
45
+ linecache19 (>= 0.5.11)
46
+ ruby_core_source (>= 0.1.4)
47
+ ruby-debug19 (0.11.6)
48
+ columnize (>= 0.3.1)
49
+ linecache19 (>= 0.5.11)
50
+ ruby-debug-base19 (>= 0.11.19)
51
+ ruby_core_source (0.1.5)
52
+ archive-tar-minitar (>= 0.5.2)
53
+ simplecov (0.4.2)
54
+ simplecov-html (~> 0.4.4)
55
+ simplecov-html (0.4.5)
56
+ sinatra (1.2.6)
57
+ rack (~> 1.1)
58
+ tilt (>= 1.2.2, < 2.0)
59
+ tilt (1.3.2)
60
+ vegas (0.1.8)
61
+ rack (>= 1.0.0)
62
+
63
+ PLATFORMS
64
+ ruby
65
+
66
+ DEPENDENCIES
67
+ rack-test
68
+ resque (>= 1.9.10)
69
+ resque-pause!
70
+ rspec (>= 2.3.0)
71
+ ruby-debug
72
+ ruby-debug19
73
+ simplecov (>= 0.4.2)
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ Resque Pause
2
+ ============
3
+
4
+ A [Resque][rq] plugin. Requires Resque 1.9.10.
5
+
6
+ resque-pause adds functionality to pause resque jobs through the web interface.
7
+
8
+ Using a `pause` allows you to stop the job for a slice of time.
9
+ The job finish the process it are doing and don't get a new task to do,
10
+ until the queue is released.
11
+ You can use this functionality to do some maintenance whithout kill workers, for example.
12
+
13
+ Usage / Examples
14
+ ----------------
15
+
16
+ ### Single Job Instance
17
+
18
+ require 'resque-pause'
19
+
20
+ class UpdateNetworkGraph
21
+ extend Resque::Plugins::Pause
22
+ @queue = :network_graph
23
+
24
+ def self.perform(repo_id)
25
+ heavy_lifting
26
+ end
27
+ end
28
+
29
+ Pause is achieved by storing a pause/queue key in Redis.
30
+
31
+ Default behaviour...
32
+
33
+ * When the job instance try to execute and the queue is paused, the job is paused for a slice of time.
34
+ * If the queue still paused after this time the job will abort and will be enqueued again with the same arguments.
35
+
36
+
37
+ Resque-Web integration
38
+ ----------------------
39
+
40
+ You have to load ResquePause to enable the Pause tab.
41
+
42
+ ```ruby
43
+ require 'resque_pause'
44
+ ```
45
+
46
+ Customise & Extend
47
+ ==================
48
+
49
+ ### Job pause check interval
50
+
51
+ The slice of time the job will wait for queue be unpaused before abort the job
52
+ could be changed with attribute @pause_check_interval.
53
+
54
+ By default the time is 10 seconds.
55
+
56
+ You can define the attribute in your job class in seconds.
57
+
58
+ class UpdateNetworkGraph
59
+ extend Resque::Plugins::Pause
60
+ @queue = :network_graph
61
+ @pause_check_interval = 30
62
+
63
+ def self.perform(repo_id)
64
+ heavy_lifting
65
+ end
66
+ end
67
+
68
+ The above modification will ensure the job will wait for 30 seconds before abort.
69
+
70
+
71
+ Install
72
+ =======
73
+
74
+ $ gem install resque-pause
75
+
76
+ [rq]: http://github.com/defunkt/resque
77
+ [resque-pause]: https://github.com/wandenberg/resque-pause
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec/core/rake_task"
5
+
6
+ desc "Run all examples"
7
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,3 @@
1
+ require 'resque'
2
+ require File.expand_path(File.join('resque_pause_helper'), File.dirname(__FILE__))
3
+ require File.expand_path(File.join('resque', 'plugins', 'pause'), File.dirname(__FILE__))
@@ -0,0 +1,15 @@
1
+ module Resque
2
+ module Plugins
3
+ module Pause
4
+ include Resque::Helpers
5
+ PAUSE_CHECK_INTERVAL = 10 #seconds to wait when queue is paused
6
+
7
+ def before_perform_pause(*args)
8
+ if ResquePauseHelper.paused?(@queue)
9
+ Kernel.sleep(@pause_check_interval || Resque::Plugins::Pause::PAUSE_CHECK_INTERVAL)
10
+ ResquePauseHelper.check_paused(:queue => @queue, :class => self, :args => args)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ require 'resque'
2
+ require 'resque/server'
3
+ require File.expand_path(File.join('resque_pause_helper'), File.dirname(__FILE__))
4
+ require File.expand_path(File.join('resque_pause', 'server'), File.dirname(__FILE__))
@@ -0,0 +1,56 @@
1
+ # Extends Resque Web Based UI.
2
+ # Structure has been borrowed from ResqueScheduler.
3
+ module ResquePause
4
+ module Server
5
+ include Resque::Helpers
6
+
7
+ def self.erb_path(filename)
8
+ File.join(File.dirname(__FILE__), 'server', 'views', filename)
9
+ end
10
+
11
+ def self.public_path(filename)
12
+ File.join(File.dirname(__FILE__), 'server', 'public', filename)
13
+ end
14
+
15
+ def self.included(base)
16
+
17
+ base.class_eval do
18
+
19
+ helpers do
20
+ def paused?(queue)
21
+ ResquePauseHelper.paused?(queue)
22
+ end
23
+ end
24
+
25
+ mime_type :json, 'application/json'
26
+
27
+ get '/pause' do
28
+ erb File.read(ResquePause::Server.erb_path('pause.erb'))
29
+ end
30
+
31
+ post '/pause' do
32
+ ResquePauseHelper.pause(params['queue_name']) unless params['queue_name'].empty?
33
+ content_type :json
34
+ encode(:queue_name => params['queue_name'], :paused => true)
35
+ end
36
+
37
+ post '/unpause' do
38
+ ResquePauseHelper.unpause(params['queue_name']) unless params['queue_name'].empty?
39
+ content_type :json
40
+ encode(:queue_name => params['queue_name'], :paused => false)
41
+ end
42
+
43
+ get /pause\/public\/([a-z]+\.[a-z]+)/ do
44
+ send_file ResquePause::Server.public_path(params[:captures].first)
45
+ end
46
+ end
47
+ end
48
+
49
+ Resque::Server.tabs << 'Pause'
50
+ end
51
+ end
52
+
53
+ Resque.extend ResquePause
54
+ Resque::Server.class_eval do
55
+ include ResquePause::Server
56
+ end
@@ -0,0 +1,18 @@
1
+ jQuery(document).ready(function($) {
2
+ $('input:checkbox.pause').click( function(){
3
+ var queue = $(this);
4
+ var data = {'queue_name': queue.val()};
5
+ var url = queue.is(':checked') ? '/pause' : '/unpause';
6
+ $.ajax({
7
+ type: 'POST',
8
+ url: url,
9
+ data: data,
10
+ async: false,
11
+ cache: false,
12
+ success: function() { return true; },
13
+ error: function() { return false; },
14
+ dataType: 'json'
15
+ });
16
+
17
+ });
18
+ });
@@ -0,0 +1,18 @@
1
+ <script src="<%=u '/pause/public/pause.js' %>" type="text/javascript"></script>
2
+
3
+ <h1 class='wi'>Queues</h1>
4
+ <p class='intro'>The list below contains all the registered queues with the status if is paused or not. Select a queue from above to pause processing jobs.</p>
5
+ <table class='queues1'>
6
+ <tr>
7
+ <th>Name</th>
8
+ <th>Paused</th>
9
+ <th>Jobs</th>
10
+ </tr>
11
+ <% for queue in resque.queues.sort_by { |q| q.to_s } %>
12
+ <tr>
13
+ <td class='queue'><%= queue %></td>
14
+ <td class='status'><input class="pause" type="checkbox" value="<%= queue%>" <%= "checked" if paused?(queue) %>></input></td>
15
+ <td class='size'><%= resque.size queue %></td>
16
+ </tr>
17
+ <% end %>
18
+ </table>
@@ -0,0 +1,30 @@
1
+ module ResquePauseHelper
2
+ class << self
3
+ def paused?(queue)
4
+ !Resque.redis.get("pause:queue:#{queue}").nil?
5
+ end
6
+
7
+ def pause(queue)
8
+ Resque.redis.set "pause:queue:#{queue}", true
9
+ end
10
+
11
+ def unpause(queue)
12
+ Resque.redis.del "pause:queue:#{queue}"
13
+ end
14
+
15
+ def enqueue_job(args)
16
+ Resque.redis.lpush("queue:#{args[:queue]}", Resque.encode(:class => args[:class], :args => args[:args]))
17
+ end
18
+
19
+ def dequeue_job(args)
20
+ Resque.redis.lpop("queue:#{args[:queue]}")
21
+ end
22
+
23
+ def check_paused(args)
24
+ if ResquePauseHelper.paused?(args[:queue])
25
+ enqueue_job(args)
26
+ raise Resque::Job::DontPerform.new "Queue #{args[:queue]} is paused!"
27
+ end
28
+ end
29
+ end
30
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Resque
2
+ module Plugins
3
+ module Pause
4
+ VERSION = "0.0.2"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "resque-pause"
7
+ s.version = Resque::Plugins::Pause::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Wandenberg Peixoto"]
10
+ s.email = ["wandenberg@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{A Resque plugin to add functionality to pause resque jobs through the web interface.}
13
+ s.description = %q{A Resque plugin to add functionality to pause resque jobs through the web interface.
14
+
15
+ Using a `pause` allows you to stop the job for a slice of time.
16
+ The job finish the process it are doing and don't get a new task to do,
17
+ until the queue is released.
18
+ You can use this functionality to do some maintenance whithout kill workers, for example.}
19
+
20
+ s.rubyforge_project = "resque-pause"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ s.has_rdoc = false
27
+
28
+ s.add_dependency('resque', '>= 1.9.10')
29
+
30
+ s.add_development_dependency('rspec', '>= 2.3.0')
31
+ s.add_development_dependency('rack-test')
32
+ s.add_development_dependency('simplecov', '>= 0.4.2')
33
+
34
+ end
@@ -0,0 +1,115 @@
1
+ # Redis configuration file example
2
+
3
+ # By default Redis does not run as a daemon. Use 'yes' if you need it.
4
+ # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
5
+ daemonize yes
6
+
7
+ # When run as a daemon, Redis write a pid file in /var/run/redis.pid by default.
8
+ # You can specify a custom pid file location here.
9
+ pidfile ./spec/redis-test.pid
10
+
11
+ # Accept connections on the specified port, default is 6379
12
+ port 9736
13
+
14
+ # If you want you can bind a single interface, if the bind option is not
15
+ # specified all the interfaces will listen for connections.
16
+ #
17
+ # bind 127.0.0.1
18
+
19
+ # Close the connection after a client is idle for N seconds (0 to disable)
20
+ timeout 300
21
+
22
+ # Save the DB on disk:
23
+ #
24
+ # save <seconds> <changes>
25
+ #
26
+ # Will save the DB if both the given number of seconds and the given
27
+ # number of write operations against the DB occurred.
28
+ #
29
+ # In the example below the behaviour will be to save:
30
+ # after 900 sec (15 min) if at least 1 key changed
31
+ # after 300 sec (5 min) if at least 10 keys changed
32
+ # after 60 sec if at least 10000 keys changed
33
+ save 900 1
34
+ save 300 10
35
+ save 60 10000
36
+
37
+ # The filename where to dump the DB
38
+ dbfilename dump.rdb
39
+
40
+ # For default save/load DB in/from the working directory
41
+ # Note that you must specify a directory not a file name.
42
+ dir ./spec/
43
+
44
+ # Set server verbosity to 'debug'
45
+ # it can be one of:
46
+ # debug (a lot of information, useful for development/testing)
47
+ # notice (moderately verbose, what you want in production probably)
48
+ # warning (only very important / critical messages are logged)
49
+ loglevel debug
50
+
51
+ # Specify the log file name. Also 'stdout' can be used to force
52
+ # the demon to log on the standard output. Note that if you use standard
53
+ # output for logging but daemonize, logs will be sent to /dev/null
54
+ logfile stdout
55
+
56
+ # Set the number of databases. The default database is DB 0, you can select
57
+ # a different one on a per-connection basis using SELECT <dbid> where
58
+ # dbid is a number between 0 and 'databases'-1
59
+ databases 16
60
+
61
+ ################################# REPLICATION #################################
62
+
63
+ # Master-Slave replication. Use slaveof to make a Redis instance a copy of
64
+ # another Redis server. Note that the configuration is local to the slave
65
+ # so for example it is possible to configure the slave to save the DB with a
66
+ # different interval, or to listen to another port, and so on.
67
+
68
+ # slaveof <masterip> <masterport>
69
+
70
+ ################################## SECURITY ###################################
71
+
72
+ # Require clients to issue AUTH <PASSWORD> before processing any other
73
+ # commands. This might be useful in environments in which you do not trust
74
+ # others with access to the host running redis-server.
75
+ #
76
+ # This should stay commented out for backward compatibility and because most
77
+ # people do not need auth (e.g. they run their own servers).
78
+
79
+ # requirepass foobared
80
+
81
+ ################################### LIMITS ####################################
82
+
83
+ # Set the max number of connected clients at the same time. By default there
84
+ # is no limit, and it's up to the number of file descriptors the Redis process
85
+ # is able to open. The special value '0' means no limts.
86
+ # Once the limit is reached Redis will close all the new connections sending
87
+ # an error 'max number of clients reached'.
88
+
89
+ # maxclients 128
90
+
91
+ # Don't use more memory than the specified amount of bytes.
92
+ # When the memory limit is reached Redis will try to remove keys with an
93
+ # EXPIRE set. It will try to start freeing keys that are going to expire
94
+ # in little time and preserve keys with a longer time to live.
95
+ # Redis will also try to remove objects from free lists if possible.
96
+ #
97
+ # If all this fails, Redis will start to reply with errors to commands
98
+ # that will use more memory, like SET, LPUSH, and so on, and will continue
99
+ # to reply to most read-only commands like GET.
100
+ #
101
+ # WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
102
+ # 'state' server or cache, not as a real DB. When Redis is used as a real
103
+ # database the memory usage will grow over the weeks, it will be obvious if
104
+ # it is going to use too much memory in the long run, and you'll have the time
105
+ # to upgrade. With maxmemory after the limit is reached you'll start to get
106
+ # errors for write operations, and this may even lead to DB inconsistency.
107
+
108
+ # maxmemory <bytes>
109
+
110
+ ############################### ADVANCED CONFIG ###############################
111
+
112
+ # Glue small output buffers together in order to send small replies in a
113
+ # single TCP packet. Uses a bit more CPU but most of the times it is a win
114
+ # in terms of number of queries per second. Use 'yes' if unsure.
115
+ glueoutputbuf yes
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe ResquePause::Server do
4
+ include Rack::Test::Methods
5
+ def app
6
+ @app ||= Resque::Server.new
7
+ end
8
+
9
+ let :queues do
10
+ Resque.redis.sadd(:queues, "queue1")
11
+ Resque.redis.sadd(:queues, "queue2")
12
+ Resque.redis.sadd(:queues, "queue3")
13
+ end
14
+
15
+ before do
16
+ queues
17
+ end
18
+
19
+ it "should respond to /pause" do
20
+ get '/pause'
21
+ last_response.should be_ok
22
+ end
23
+
24
+ it "should list all registered queues" do
25
+ get '/pause'
26
+ last_response.body.should include("queue1")
27
+ last_response.body.should include("queue2")
28
+ last_response.body.should include("queue3")
29
+ end
30
+
31
+ it "should check paused queues" do
32
+ ResquePauseHelper.pause("queue2")
33
+
34
+ get '/pause'
35
+ last_response.body.should include(%q{<input class="pause" type="checkbox" value="queue1" ></input>})
36
+ last_response.body.should include(%q{<input class="pause" type="checkbox" value="queue2" checked></input>})
37
+ last_response.body.should include(%q{<input class="pause" type="checkbox" value="queue3" ></input>})
38
+ end
39
+
40
+
41
+ it "should pause a queue" do
42
+ post "/pause", :queue_name => "queue3"
43
+
44
+ ResquePauseHelper.paused?("queue3").should be_true
45
+ end
46
+
47
+ it "should return a json when pause a queue" do
48
+ post "/pause", :queue_name => "queue3"
49
+
50
+ last_response.headers["Content-Type"].should == "application/json"
51
+ last_response.body.should == { :queue_name => "queue3", :paused => true }.to_json
52
+ end
53
+
54
+ it "should unpause a queue" do
55
+ ResquePauseHelper.pause("queue2")
56
+ post "/unpause", :queue_name => "queue2"
57
+
58
+ ResquePauseHelper.paused?("queue2").should be_false
59
+ end
60
+
61
+ it "should return a json when unpause a queue" do
62
+ post "/unpause", :queue_name => "queue2"
63
+
64
+ last_response.headers["Content-Type"].should == "application/json"
65
+ last_response.body.should == { :queue_name => "queue2", :paused => false }.to_json
66
+ end
67
+
68
+ it "should return static files" do
69
+ get "/pause/public/pause.js"
70
+ last_response.body.should == File.read(File.expand_path('../lib/resque_pause/server/public/pause.js', File.dirname(__FILE__)))
71
+ end
72
+
73
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ class PauseJob
4
+ extend Resque::Plugins::Pause
5
+ @queue = :test
6
+
7
+ def self.perform(*args)
8
+ end
9
+ end
10
+
11
+ describe Resque::Plugins::Pause do
12
+ it "should be compliance with Resqu::Plugin document" do
13
+ expect { Resque::Plugin.lint(Resque::Plugins::Pause) }.to_not raise_error
14
+ end
15
+
16
+ it "should use at least resque version 1.8.0" do
17
+ major, minor, patch = Resque::Version.split('.')
18
+ major.to_i.should == 1
19
+ minor.to_i.should >= 8
20
+ end
21
+
22
+ it "should execute the job when queue is not paused" do
23
+ Resque.enqueue(PauseJob)
24
+ PauseJob.should_receive(:perform)
25
+
26
+ Resque.reserve('test').perform
27
+ end
28
+
29
+ it "should not execute the job when queue is paused" do
30
+ ResquePauseHelper.pause('test')
31
+ Resque.enqueue(PauseJob)
32
+ PauseJob.should_not_receive(:perform)
33
+
34
+ Resque.reserve('test').perform
35
+ end
36
+
37
+ it "should not change queued jobs when queue is paused" do
38
+ ResquePauseHelper.pause('test')
39
+ Resque.enqueue(PauseJob, 1)
40
+ Resque.enqueue(PauseJob, 2)
41
+ Resque.enqueue(PauseJob, 3)
42
+ jobs = Resque.redis.lrange('queue:test', 0, 2)
43
+
44
+ Resque.reserve('test').perform
45
+
46
+ remaining_jobs = Resque.redis.lrange('queue:test', 0, 2)
47
+ jobs.should == remaining_jobs
48
+ end
49
+
50
+ it "should back to execute the job when queue is unpaused" do
51
+ Resque.enqueue(PauseJob)
52
+
53
+ ResquePauseHelper.pause('test')
54
+ Resque.reserve('test').perform
55
+ Resque.size('test').should == 1
56
+
57
+ ResquePauseHelper.unpause('test')
58
+ Resque.reserve('test').perform
59
+ Resque.size('test').should == 0
60
+ end
61
+
62
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ class PauseJob
4
+ @queue = :test
5
+
6
+ def self.perform(*args)
7
+ end
8
+ end
9
+
10
+ describe ResquePauseHelper do
11
+
12
+ context "when check queue status" do
13
+ it "should return return false if don't have register on redis" do
14
+ Resque.redis.del "pause:queue:queue1"
15
+
16
+ subject.paused?("queue1").should be_false
17
+ end
18
+
19
+ it "should return return true if have register on redis" do
20
+ Resque.redis.set "pause:queue:queue1", "AnyValue"
21
+
22
+ subject.paused?("queue1").should be_true
23
+ end
24
+ end
25
+
26
+ context "when pause a queue" do
27
+ it "should register a unregistred queue" do
28
+ Resque.redis.del "pause:queue:queue1"
29
+ subject.pause("queue1")
30
+
31
+ subject.paused?("queue1").should be_true
32
+ end
33
+
34
+ it "should register again a registred queue" do
35
+ Resque.redis.set "pause:queue:queue1", "AnyValue"
36
+ expect { subject.pause("queue1") }.to_not raise_error
37
+
38
+ Resque.redis.get("pause:queue:queue1").should_not be_nil
39
+ Resque.redis.get("pause:queue:queue1").should be_true
40
+ end
41
+ end
42
+
43
+ context "when unpause a queue" do
44
+ it "should unregister a unregistred queue" do
45
+ Resque.redis.del "pause:queue:queue1"
46
+ subject.unpause("queue1")
47
+
48
+ subject.paused?("queue1").should be_false
49
+ end
50
+
51
+ it "should unregister a registred queue" do
52
+ Resque.redis.set "pause:queue:queue1", "AnyValue"
53
+ expect { subject.unpause("queue1") }.to_not raise_error
54
+
55
+ Resque.redis.get("pause:queue:queue1").should be_nil
56
+ end
57
+ end
58
+
59
+ context "when enqueue a job" do
60
+ it "should enqueue on a empty queue" do
61
+ Resque.redis.del "queue:queue1"
62
+
63
+ subject.enqueue_job(:queue => "queue1", :class => PauseJob, :args => nil)
64
+
65
+ Resque.redis.llen("queue:queue1").to_i.should == 1
66
+ end
67
+
68
+ it "should enqueue on beginning of a queue" do
69
+ Resque.redis.lpush "queue:queue1", {:class => PauseJob, :args => [1, 2]}.to_json
70
+
71
+ subject.enqueue_job(:queue => "queue1", :class => PauseJob, :args => [1])
72
+
73
+ jobs = Resque.redis.lrange('queue:queue1', 0, 10)
74
+
75
+ jobs.count.should == 2
76
+ jobs[0].should == {:class => PauseJob, :args => [1]}.to_json
77
+ jobs[1].should == {:class => PauseJob, :args => [1, 2]}.to_json
78
+ end
79
+ end
80
+
81
+ context "when dequeue a job" do
82
+ it "should not get error when queue is empty" do
83
+ Resque.redis.del "queue:queue1"
84
+
85
+ expect { subject.dequeue_job(:queue => "queue1") }.to_not raise_error
86
+
87
+ subject.dequeue_job(:queue => "queue1").should be_nil
88
+ end
89
+
90
+ it "should get the job on beginning of a queue" do
91
+ Resque.redis.lpush "queue:queue1", {:class => PauseJob, :args => [1, 2]}.to_json
92
+ Resque.redis.lpush "queue:queue1", {:class => PauseJob, :args => [1]}.to_json
93
+
94
+ job = subject.dequeue_job(:queue => "queue1")
95
+ job.should == {:class => PauseJob, :args => [1]}.to_json
96
+ end
97
+ end
98
+
99
+ context "when checking if queue is paused" do
100
+ it "should check if queue is paused" do
101
+ subject.should_receive(:paused?).with("queue1")
102
+
103
+ subject.check_paused(:queue => "queue1")
104
+ end
105
+
106
+ it "should not raise error when queue is not paused" do
107
+ subject.should_receive(:paused?).with("queue1").and_return(false)
108
+
109
+ expect { subject.check_paused(:queue => "queue1") }.to_not raise_error
110
+ end
111
+
112
+ it "should raise error when queue is paused" do
113
+ subject.stub!(:enqueue_job)
114
+ subject.stub!(:paused?).with("queue1").and_return(true)
115
+
116
+ expect { subject.check_paused(:queue => "queue1") }.to raise_error(Resque::Job::DontPerform)
117
+ end
118
+
119
+ it "should enqueue the job again when queue is paused" do
120
+ subject.stub!(:paused?).with("queue1").and_return(true)
121
+
122
+ args = {:queue => "queue1", :class => PauseJob, :args => [1, 2]}
123
+ subject.should_receive(:enqueue_job).with(args)
124
+
125
+ subject.check_paused(args) rescue nil
126
+ end
127
+ end
128
+
129
+ end
@@ -0,0 +1,65 @@
1
+ require 'rack/test'
2
+
3
+ if !system("which redis-server")
4
+ puts '', "** can't find `redis-server` in your path"
5
+ abort ''
6
+ end
7
+
8
+ begin
9
+ require 'simplecov'
10
+ SimpleCov.start do
11
+ add_filter '/spec/'
12
+ end
13
+ SimpleCov.coverage_dir 'coverage'
14
+ rescue LoadError
15
+ # ignore simplecov in ruby < 1.9
16
+ end
17
+
18
+ begin
19
+ require 'bundler'
20
+ Bundler.setup
21
+ Bundler.require(:default, :development)
22
+ rescue LoadError
23
+ puts 'Bundler is not installed, you need to gem install it in order to run the specs.'
24
+ exit 1
25
+ end
26
+
27
+ # Requires supporting files with custom matchers and macros, etc,
28
+ # in ./support/ and its subdirectories.
29
+ Dir[File.expand_path('support/**/*.rb', File.dirname(__FILE__))].each { |f| require f }
30
+
31
+ # Requires lib.
32
+ Dir[File.expand_path('../lib/**/*.rb', File.dirname(__FILE__))].each { |f| require f }
33
+
34
+ RSpec.configure do |config|
35
+ # == Mock Framework
36
+ #
37
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
38
+ #
39
+ # config.mock_with :mocha
40
+ # config.mock_with :flexmock
41
+ # config.mock_with :rr
42
+ config.mock_with :rspec
43
+
44
+ config.before(:suite) do
45
+ puts "Starting redis for testing at localhost:9736..."
46
+ `redis-server #{File.dirname(File.expand_path(__FILE__))}/redis-test.conf`
47
+ pid = ''
48
+ while pid.empty? do
49
+ pid = `ps -e -o pid,command | grep [r]edis-test`.split(" ")[0]
50
+ end
51
+ Resque.redis = '127.0.0.1:9736'
52
+ end
53
+
54
+ config.before(:each) do
55
+ Resque.redis.flushall
56
+ Kernel.stub!(:sleep)
57
+ end
58
+
59
+ config.after(:suite) do
60
+ pid = `ps -e -o pid,command | grep [r]edis-test`.split(" ")[0]
61
+ puts '', "Killing test redis server..."
62
+ Process.kill("KILL", pid.to_i)
63
+ `rm -f #{File.dirname(File.expand_path(__FILE__))}/dump.rdb`
64
+ end
65
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resque-pause
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Wandenberg Peixoto
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-06-27 00:00:00 -03:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: resque
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 9
31
+ - 10
32
+ version: 1.9.10
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 2
45
+ - 3
46
+ - 0
47
+ version: 2.3.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rack-test
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: simplecov
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ segments:
72
+ - 0
73
+ - 4
74
+ - 2
75
+ version: 0.4.2
76
+ type: :development
77
+ version_requirements: *id004
78
+ description: |-
79
+ A Resque plugin to add functionality to pause resque jobs through the web interface.
80
+
81
+ Using a `pause` allows you to stop the job for a slice of time.
82
+ The job finish the process it are doing and don't get a new task to do,
83
+ until the queue is released.
84
+ You can use this functionality to do some maintenance whithout kill workers, for example.
85
+ email:
86
+ - wandenberg@gmail.com
87
+ executables: []
88
+
89
+ extensions: []
90
+
91
+ extra_rdoc_files: []
92
+
93
+ files:
94
+ - .gitignore
95
+ - Gemfile
96
+ - Gemfile.lock
97
+ - README.md
98
+ - Rakefile
99
+ - lib/resque-pause.rb
100
+ - lib/resque/plugins/pause.rb
101
+ - lib/resque_pause.rb
102
+ - lib/resque_pause/server.rb
103
+ - lib/resque_pause/server/public/pause.js
104
+ - lib/resque_pause/server/views/pause.erb
105
+ - lib/resque_pause_helper.rb
106
+ - lib/version.rb
107
+ - resque-pause.gemspec
108
+ - spec/redis-test.conf
109
+ - spec/resque-web_spec.rb
110
+ - spec/resque/plugins/pause_spec.rb
111
+ - spec/resque_pause_helper_spec.rb
112
+ - spec/spec_helper.rb
113
+ has_rdoc: true
114
+ homepage: ""
115
+ licenses: []
116
+
117
+ post_install_message:
118
+ rdoc_options: []
119
+
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ segments:
128
+ - 0
129
+ version: "0"
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ requirements: []
139
+
140
+ rubyforge_project: resque-pause
141
+ rubygems_version: 1.3.7
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: A Resque plugin to add functionality to pause resque jobs through the web interface.
145
+ test_files: []
146
+