jerefrer-resque 1.1.0

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.
Files changed (58) hide show
  1. data/.kick +26 -0
  2. data/HISTORY.md +10 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +703 -0
  5. data/Rakefile +61 -0
  6. data/bin/resque +69 -0
  7. data/bin/resque-web +47 -0
  8. data/config.ru +8 -0
  9. data/deps.rip +5 -0
  10. data/examples/async_helper.rb +31 -0
  11. data/examples/demo/README.markdown +71 -0
  12. data/examples/demo/Rakefile +3 -0
  13. data/examples/demo/app.rb +27 -0
  14. data/examples/demo/config.ru +19 -0
  15. data/examples/demo/job.rb +12 -0
  16. data/examples/god/resque.god +52 -0
  17. data/examples/god/stale.god +26 -0
  18. data/examples/instance.rb +11 -0
  19. data/examples/simple.rb +30 -0
  20. data/init.rb +1 -0
  21. data/lib/resque/errors.rb +7 -0
  22. data/lib/resque/failure/base.rb +58 -0
  23. data/lib/resque/failure/hoptoad.rb +88 -0
  24. data/lib/resque/failure/redis.rb +33 -0
  25. data/lib/resque/failure.rb +63 -0
  26. data/lib/resque/helpers.rb +57 -0
  27. data/lib/resque/job.rb +91 -0
  28. data/lib/resque/server/public/idle.png +0 -0
  29. data/lib/resque/server/public/jquery-1.3.2.min.js +19 -0
  30. data/lib/resque/server/public/jquery.relatize_date.js +95 -0
  31. data/lib/resque/server/public/poll.png +0 -0
  32. data/lib/resque/server/public/ranger.js +21 -0
  33. data/lib/resque/server/public/reset.css +48 -0
  34. data/lib/resque/server/public/style.css +75 -0
  35. data/lib/resque/server/public/working.png +0 -0
  36. data/lib/resque/server/views/error.erb +1 -0
  37. data/lib/resque/server/views/failed.erb +35 -0
  38. data/lib/resque/server/views/key.erb +17 -0
  39. data/lib/resque/server/views/layout.erb +41 -0
  40. data/lib/resque/server/views/next_more.erb +10 -0
  41. data/lib/resque/server/views/overview.erb +4 -0
  42. data/lib/resque/server/views/queues.erb +46 -0
  43. data/lib/resque/server/views/stats.erb +62 -0
  44. data/lib/resque/server/views/workers.erb +78 -0
  45. data/lib/resque/server/views/working.erb +67 -0
  46. data/lib/resque/server.rb +174 -0
  47. data/lib/resque/stat.rb +53 -0
  48. data/lib/resque/tasks.rb +24 -0
  49. data/lib/resque/version.rb +3 -0
  50. data/lib/resque/worker.rb +406 -0
  51. data/lib/resque.rb +184 -0
  52. data/tasks/redis.rake +125 -0
  53. data/tasks/resque.rake +2 -0
  54. data/test/redis-test.conf +132 -0
  55. data/test/resque_test.rb +160 -0
  56. data/test/test_helper.rb +90 -0
  57. data/test/worker_test.rb +220 -0
  58. metadata +121 -0
@@ -0,0 +1,35 @@
1
+ <%start = params[:start].to_i %>
2
+ <%failed = Resque::Failure.all(start, 20)%>
3
+
4
+ <h1>Failed Jobs</h1>
5
+ <%unless failed.empty?%>
6
+ <form method="POST" action="<%=u 'failed/clear'%>" class='clear-failed'>
7
+ <input type='submit' name='' value='Clear Failed Jobs' />
8
+ </form>
9
+ <%end%>
10
+
11
+ <p class='sub'>Showing <%=start%> to <%= start + 20 %> of <b><%= size = Resque::Failure.count %></b> jobs</p>
12
+
13
+ <ul class='failed'>
14
+ <%for job in failed%>
15
+ <li>
16
+ <dl>
17
+ <dt>Worker</dt>
18
+ <dd><a href="<%= url(:workers, job['worker']) %>"><%= job['worker'].split(':')[0...2].join(':') %></a> on <b class='queue-tag'><%= job['queue'] %></b > at <b><span class="time"><%= job['failed_at'] %></span></b></dd>
19
+ <dt>Class</dt>
20
+ <dd><code><%= job['payload']['class'] %></code></dd>
21
+ <dt>Arguments</dt>
22
+ <dd><pre><%=h show_args(job['payload']['args']) %></pre></dd>
23
+ <dt>Error</dt>
24
+ <dd class='error'>
25
+ <a href="#" class="backtrace"><%= h(job['error']) %></a>
26
+ <pre style='display:none'><%=h job['backtrace'].join("\n") %></pre>
27
+ </dd>
28
+ </dl>
29
+ <div class='r'>
30
+ </div>
31
+ </li>
32
+ <%end%>
33
+ </ul>
34
+
35
+ <%= partial :next_more, :start => start, :size => size %>
@@ -0,0 +1,17 @@
1
+ <% if key = params[:key] %>
2
+
3
+ <h1>Key "<%= key %>" is a <%= resque.redis.type key %></h1>
4
+ <h2>size: <%= redis_get_size(key) %></h2>
5
+ <table>
6
+ <% for row in redis_get_value_as_array(key) %>
7
+ <tr>
8
+ <td>
9
+ <%= row %>
10
+ </td>
11
+ </tr>
12
+ <% end %>
13
+ </table>
14
+
15
+ <% else %>
16
+
17
+ <% end %>
@@ -0,0 +1,41 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Resque.</title>
5
+ <link href="<%=u 'reset.css' %>" media="screen" rel="stylesheet" type="text/css">
6
+ <link href="<%=u 'style.css' %>" media="screen" rel="stylesheet" type="text/css">
7
+ <script src="<%=u 'jquery-1.3.2.min.js' %>" type="text/javascript"</script>
8
+ <script src="<%=u 'jquery.relatize_date.js' %>" type="text/javascript"</script>
9
+ <script src="<%=u 'ranger.js' %>" type="text/javascript"></script>
10
+ </head>
11
+ <body>
12
+ <div class="header">
13
+ <ul class='nav'>
14
+ <%= tab "Overview" %>
15
+ <%= tab "Working" %>
16
+ <%= tab "Failed" %>
17
+ <%= tab "Queues" %>
18
+ <%= tab "Workers" %>
19
+ <%= tab "Stats" %>
20
+ </ul>
21
+ </div>
22
+
23
+ <% if @subtabs %>
24
+ <ul class='subnav'>
25
+ <% for subtab in @subtabs %>
26
+ <li <%= class_if_current "#{current_section}/#{subtab}" %>><a href="<%= current_section %>/<%= subtab %>"><span><%= subtab %></span></a></li>
27
+ <% end %>
28
+ </ul>
29
+ <% end %>
30
+
31
+ <div id="main">
32
+ <%= yield %>
33
+ </div>
34
+
35
+ <div id="footer">
36
+ <p>Powered by <a href="http://github.com/defunkt/resque">Resque</a> v<%=Resque::Version%></p>
37
+ <p>Connected to Redis on <%=Resque.redis.server%></p>
38
+ </div>
39
+
40
+ </body>
41
+ </html>
@@ -0,0 +1,10 @@
1
+ <%if start - 20 >= 0 || start + 20 <= size%>
2
+ <p class='pagination'>
3
+ <% if start - 20 >= 0 %>
4
+ <a href="<%= current_page %>?start=<%= start - 20 %>" class='less'>&laquo; less</a>
5
+ <% end %>
6
+ <% if start + 20 <= size %>
7
+ <a href="<%= current_page %>?start=<%= start + 20 %>" class='more'>more &raquo;</a>
8
+ <% end %>
9
+ </p>
10
+ <%end%>
@@ -0,0 +1,4 @@
1
+ <%= partial :queues %>
2
+ <hr />
3
+ <%= partial :working %>
4
+ <%= poll %>
@@ -0,0 +1,46 @@
1
+ <% @subtabs = resque.queues unless partial? %>
2
+
3
+ <% if queue = params[:id] %>
4
+
5
+ <h1>Pending jobs on <span class='hl'><%= queue %></span></h1>
6
+ <p class='sub'>Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <b><%=size = resque.size(queue)%></b> jobs</p>
7
+ <table class='jobs'>
8
+ <tr>
9
+ <th>Class</th>
10
+ <th>Args</th>
11
+ </tr>
12
+ <% for job in (jobs = resque.peek(queue, start, 20)) %>
13
+ <tr>
14
+ <td class='class'><%= job['class'] %></td>
15
+ <td class='args'><%=h job['args'].inspect %></td>
16
+ </tr>
17
+ <% end %>
18
+ <% if jobs.empty? %>
19
+ <tr>
20
+ <td class='no-data' colspan='2'>There are no pending jobs in this queue</td>
21
+ </tr>
22
+ <% end %>
23
+ </table>
24
+ <%= partial :next_more, :start => start, :size => size %>
25
+ <% else %>
26
+
27
+ <h1 class='wi'>Queues</h1>
28
+ <p class='intro'>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.</p>
29
+ <table class='queues'>
30
+ <tr>
31
+ <th>Name</th>
32
+ <th>Jobs</th>
33
+ </tr>
34
+ <% for queue in resque.queues.sort_by { |q| q.to_s } %>
35
+ <tr>
36
+ <td class='queue'><a class="queue" href="<%= url "queues/#{queue}" %>"><%= queue %></a></td>
37
+ <td class='size'><%= resque.size queue %></td>
38
+ </tr>
39
+ <% end %>
40
+ <tr class='failed'>
41
+ <td class='queue failed'><a class="queue" href="<%= url :failed %>">failed</a></td>
42
+ <td class='size'><%= Resque::Failure.count %></td>
43
+ </tr>
44
+ </table>
45
+
46
+ <% end %>
@@ -0,0 +1,62 @@
1
+ <% @subtabs = %w( resque redis keys ) %>
2
+
3
+ <% if params[:key] %>
4
+
5
+ <%= partial :key %>
6
+
7
+ <% elsif params[:id] == "resque" %>
8
+
9
+ <h1><%= resque %></h1>
10
+ <table class='stats'>
11
+ <% for key, value in resque.info.to_a.sort_by { |i| i[0].to_s } %>
12
+ <tr>
13
+ <th>
14
+ <%= key %>
15
+ </th>
16
+ <td>
17
+ <%= value %>
18
+ </td>
19
+ </tr>
20
+ <% end %>
21
+ </table>
22
+
23
+ <% elsif params[:id] == 'redis' %>
24
+
25
+ <h1><%= resque.redis.server %></h1>
26
+ <table class='stats'>
27
+ <% for key, value in resque.redis.info.to_a.sort_by { |i| i[0].to_s } %>
28
+ <tr>
29
+ <th>
30
+ <%= key %>
31
+ </th>
32
+ <td>
33
+ <%= value %>
34
+ </td>
35
+ </tr>
36
+ <% end %>
37
+ </table>
38
+
39
+ <% elsif params[:id] == 'keys' %>
40
+
41
+ <h1>Keys owned by <%= resque %></h1>
42
+ <p class='sub'>(All keys are actually prefixed with "resque:")</p>
43
+ <table class='stats'>
44
+ <tr>
45
+ <th>key</th>
46
+ <th>type</th>
47
+ <th>size</th>
48
+ </tr>
49
+ <% for key in resque.keys.sort %>
50
+ <tr>
51
+ <th>
52
+ <a href="/stats/keys/<%= key %>"><%= key %></a>
53
+ </th>
54
+ <td><%= resque.redis.type key %></td>
55
+ <td><%= redis_get_size key %></td>
56
+ </tr>
57
+ <% end %>
58
+ </table>
59
+
60
+ <% else %>
61
+
62
+ <% end %>
@@ -0,0 +1,78 @@
1
+ <% if params[:id] && worker = Resque::Worker.find(params[:id]) %>
2
+
3
+ <h1>Worker <%= worker %></h1>
4
+ <table class='workers'>
5
+ <tr>
6
+ <th>&nbsp;</th>
7
+ <th>Host</th>
8
+ <th>Pid</th>
9
+ <th>Started</th>
10
+ <th>Queues</th>
11
+ <th>Processed</th>
12
+ <th>Failed</th>
13
+ <th>Processing</th>
14
+ </tr>
15
+ <tr>
16
+ <td class='icon'><img src="<%=u state = worker.state %>.png" alt="<%= state %>" title="<%= state %>"></td>
17
+
18
+ <% host, pid, queues = worker.to_s.split(':') %>
19
+ <td><%= host %></td>
20
+ <td><%= pid %></td>
21
+ <td><span class="time"><%= worker.started %></a></td>
22
+ <td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + u("/queues/#{q}") + '">' + q + '</a>'}.join('') %></td>
23
+ <td><%= worker.processed %></td>
24
+ <td><%= worker.failed %></td>
25
+ <td class='process'>
26
+ <% data = worker.processing || {} %>
27
+ <% if data['queue'] %>
28
+ <code><%= data['payload']['class'] %></code>
29
+ <small><a class="queue time" href="<%=u "/working/#{worker}" %>"><%= data['run_at'] %></a></small>
30
+ <% else %>
31
+ <span class='waiting'>Waiting for a job...</span>
32
+ <% end %>
33
+ </td>
34
+ </tr>
35
+ </table>
36
+
37
+ <% elsif params[:id] %>
38
+
39
+ <h1>Worker doesn't exist</h1>
40
+
41
+ <% else %>
42
+
43
+ <h1 class='wi'><%= resque.workers.size %> Workers</h1>
44
+ <p class='intro'>The workers listed below are all registered as active on your system.</p>
45
+ <table class='workers'>
46
+ <tr>
47
+ <th>&nbsp;</th>
48
+ <th>Where</th>
49
+ <th>Queues</th>
50
+ <th>Processing</th>
51
+ </tr>
52
+ <% for worker in (workers = resque.workers.sort_by { |w| w.to_s }) %>
53
+ <tr class="<%=state = worker.state%>">
54
+ <td class='icon'><img src="<%=u state %>.png" alt="<%= state %>" title="<%= state %>"></td>
55
+
56
+ <% host, pid, queues = worker.to_s.split(':') %>
57
+ <td class='where'><a href="<%=u "workers/#{worker}"%>"><%= host %>:<%= pid %></a></td>
58
+ <td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + u("/queues/#{q}") + '">' + q + '</a>'}.join('') %></td>
59
+
60
+ <td class='process'>
61
+ <% data = worker.processing || {} %>
62
+ <% if data['queue'] %>
63
+ <code><%= data['payload']['class'] %></code>
64
+ <small><a class="queue time" href="<%=u "/working/#{worker}" %>"><%= data['run_at'] %></a></small>
65
+ <% else %>
66
+ <span class='waiting'>Waiting for a job...</span>
67
+ <% end %>
68
+ </td>
69
+ </tr>
70
+ <% end %>
71
+ <% if workers.empty? %>
72
+ <tr>
73
+ <td colspan='4' class='no-data'>There are no registered workers</td>
74
+ </tr>
75
+ <% end %>
76
+ </table>
77
+ <%=poll%>
78
+ <% end %>
@@ -0,0 +1,67 @@
1
+ <% if params[:id] && (worker = Resque::Worker.find(params[:id])) && worker.job %>
2
+ <h1><%= worker %>'s job</h1>
3
+
4
+ <table>
5
+ <tr>
6
+ <th>&nbsp;</th>
7
+ <th>Where</th>
8
+ <th>Queue</th>
9
+ <th>Started</th>
10
+ <th>Class</th>
11
+ <th>Args</th>
12
+ </tr>
13
+ <tr>
14
+ <td><img src="<%=u 'working.png' %>" alt="working" title="working"></td>
15
+ <% host, pid, _ = worker.to_s.split(':') %>
16
+ <td><a href="<%=u "/workers/#{worker}" %>"><%= host %>:<%= pid %></a></td>
17
+ <% data = worker.job %>
18
+ <% queue = data['queue'] %>
19
+ <td><a class="queue" href="<%=u "/queues/#{queue}" %>"><%= queue %></a></td>
20
+ <td><span class="time"><%= data['run_at'] %></span></td>
21
+ <td>
22
+ <code><%= data['payload']['class'] %></code>
23
+ </td>
24
+ <td><%=h data['payload']['args'].inspect %></td>
25
+ </tr>
26
+ </table>
27
+
28
+ <% else %>
29
+
30
+ <% workers = resque.working %>
31
+ <h1 class='wi'><%= workers.size %> of <%= resque.workers.size %> Workers Working</h1>
32
+ <p class='intro'>The list below contains all workers which are currently running a job.</p>
33
+ <table class='workers'>
34
+ <tr>
35
+ <th>&nbsp;</th>
36
+ <th>Where</th>
37
+ <th>Queue</th>
38
+ <th>Processing</th>
39
+ </tr>
40
+ <% if workers.empty? %>
41
+ <tr>
42
+ <td colspan="4" class='no-data'>Nothing is happening right now...</td>
43
+ </tr>
44
+ <% end %>
45
+
46
+ <% for worker in workers.sort_by { |w| w.job['run_at'] ? w.job['run_at'] : '' } %>
47
+ <% job = worker.job %>
48
+ <tr>
49
+ <td class='icon'><img src="<%=u state = worker.state %>.png" alt="<%= state %>" title="<%= state %>"></td>
50
+ <% host, pid, queues = worker.to_s.split(':') %>
51
+ <td class='where'><a href="<%=u "/workers/#{worker}" %>"><%= host %>:<%= pid %></a></td>
52
+ <td class='queues queue'>
53
+ <a class="queue-tag" href="<%=u "/queues/#{job['queue']}" %>"><%= job['queue'] %></a>
54
+ </td>
55
+ <td class='process'>
56
+ <% if job['queue'] %>
57
+ <code><%= job['payload']['class'] %></code>
58
+ <small><a class="queue time" href="<%=u "/working/#{worker}" %>"><%= job['run_at'] %></a></small>
59
+ <% else %>
60
+ <span class='waiting'>Waiting for a job...</span>
61
+ <% end %>
62
+ </td>
63
+ </tr>
64
+ <% end %>
65
+ </table>
66
+
67
+ <% end %>
@@ -0,0 +1,174 @@
1
+ require 'sinatra/base'
2
+ require 'erb'
3
+ require 'resque'
4
+ require 'resque/version'
5
+
6
+ module Resque
7
+ class Server < Sinatra::Base
8
+ dir = File.dirname(File.expand_path(__FILE__))
9
+
10
+ set :views, "#{dir}/server/views"
11
+ set :public, "#{dir}/server/public"
12
+ set :static, true
13
+
14
+ helpers do
15
+ include Rack::Utils
16
+ alias_method :h, :escape_html
17
+
18
+ def current_section
19
+ url request.path_info.sub('/','').split('/')[0].downcase
20
+ end
21
+
22
+ def current_page
23
+ url request.path_info.sub('/','').downcase
24
+ end
25
+
26
+ def url(*path_parts)
27
+ [ path_prefix, path_parts ].join("/").squeeze('/')
28
+ end
29
+ alias_method :u, :url
30
+
31
+ def path_prefix
32
+ request.env['SCRIPT_NAME']
33
+ end
34
+
35
+ def class_if_current(page = '')
36
+ 'class="current"' if current_page.include? page.to_s
37
+ end
38
+
39
+ def tab(name)
40
+ dname = name.to_s.downcase
41
+ "<li #{class_if_current(dname)}><a href='#{url dname}'>#{name}</a></li>"
42
+ end
43
+
44
+ def redis_get_size(key)
45
+ case Resque.redis.type(key)
46
+ when 'none'
47
+ []
48
+ when 'list'
49
+ Resque.redis.llen(key)
50
+ when 'set'
51
+ Resque.redis.scard(key)
52
+ when 'string'
53
+ Resque.redis.get(key).length
54
+ end
55
+ end
56
+
57
+ def redis_get_value_as_array(key)
58
+ case Resque.redis.type(key)
59
+ when 'none'
60
+ []
61
+ when 'list'
62
+ Resque.redis.lrange(key, 0, 20)
63
+ when 'set'
64
+ Resque.redis.smembers(key)
65
+ when 'string'
66
+ [Resque.redis.get(key)]
67
+ end
68
+ end
69
+
70
+ def show_args(args)
71
+ Array(args).map { |a| a.inspect }.join("\n")
72
+ end
73
+
74
+ def partial?
75
+ @partial
76
+ end
77
+
78
+ def partial(template, local_vars = {})
79
+ @partial = true
80
+ erb(template.to_sym, {:layout => false}, local_vars)
81
+ ensure
82
+ @partial = false
83
+ end
84
+
85
+ def poll
86
+ if @polling
87
+ text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
88
+ else
89
+ text = "<a href='#{url(request.path_info)}.poll' rel='poll'>Live Poll</a>"
90
+ end
91
+ "<p class='poll'>#{text}</p>"
92
+ end
93
+
94
+ end
95
+
96
+ def show(page, layout = true)
97
+ begin
98
+ erb page.to_sym, {:layout => layout}, :resque => Resque
99
+ rescue Errno::ECONNREFUSED
100
+ erb :error, {:layout => false}, :error => "Can't connect to Redis! (#{Resque.redis.server})"
101
+ end
102
+ end
103
+
104
+ # to make things easier on ourselves
105
+ get "/" do
106
+ redirect url(:overview)
107
+ end
108
+
109
+ %w( overview queues working workers key ).each do |page|
110
+ get "/#{page}" do
111
+ show page
112
+ end
113
+
114
+ get "/#{page}/:id" do
115
+ show page
116
+ end
117
+ end
118
+
119
+ %w( overview workers ).each do |page|
120
+ get "/#{page}.poll" do
121
+ content_type "text/plain"
122
+ @polling = true
123
+ show(page.to_sym, false).gsub(/\s{1,}/, ' ')
124
+ end
125
+ end
126
+
127
+ get "/failed" do
128
+ if Resque::Failure.url
129
+ redirect Resque::Failure.url
130
+ else
131
+ show :failed
132
+ end
133
+ end
134
+
135
+ post "/failed/clear" do
136
+ Resque::Failure.clear
137
+ redirect u('failed')
138
+ end
139
+
140
+ get "/stats" do
141
+ redirect url("/stats/resque")
142
+ end
143
+
144
+ get "/stats/:id" do
145
+ show :stats
146
+ end
147
+
148
+ get "/stats/keys/:key" do
149
+ show :stats
150
+ end
151
+
152
+ get "/stats.txt" do
153
+ info = Resque.info
154
+
155
+ stats = []
156
+ stats << "resque.pending=#{info[:pending]}"
157
+ stats << "resque.processed+=#{info[:processed]}"
158
+ stats << "resque.failed+=#{info[:failed]}"
159
+ stats << "resque.workers=#{info[:workers]}"
160
+ stats << "resque.working=#{info[:working]}"
161
+
162
+ Resque.queues.each do |queue|
163
+ stats << "queues.#{queue}=#{Resque.size(queue)}"
164
+ end
165
+
166
+ content_type 'text/plain'
167
+ stats.join "\n"
168
+ end
169
+
170
+ def resque
171
+ Resque
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,53 @@
1
+ module Resque
2
+ # The stat subsystem. Used to keep track of integer counts.
3
+ #
4
+ # Get a stat: Stat[name]
5
+ # Incr a stat: Stat.incr(name)
6
+ # Decr a stat: Stat.decr(name)
7
+ # Kill a stat: Stat.clear(name)
8
+ module Stat
9
+ extend self
10
+ extend Helpers
11
+
12
+ # Returns the int value of a stat, given a string stat name.
13
+ def get(stat)
14
+ redis.get("stat:#{stat}").to_i
15
+ end
16
+
17
+ # Alias of `get`
18
+ def [](stat)
19
+ get(stat)
20
+ end
21
+
22
+ # For a string stat name, increments the stat by one.
23
+ #
24
+ # Can optionally accept a second int parameter. The stat is then
25
+ # incremented by that amount.
26
+ def incr(stat, by = 1)
27
+ redis.incr("stat:#{stat}", by)
28
+ end
29
+
30
+ # Increments a stat by one.
31
+ def <<(stat)
32
+ incr stat
33
+ end
34
+
35
+ # For a string stat name, decrements the stat by one.
36
+ #
37
+ # Can optionally accept a second int parameter. The stat is then
38
+ # decremented by that amount.
39
+ def decr(stat, by = 1)
40
+ redis.decr("stat:#{stat}", by)
41
+ end
42
+
43
+ # Decrements a stat by one.
44
+ def >>(stat)
45
+ decr stat
46
+ end
47
+
48
+ # Removes a stat from Redis, effectively setting it to 0.
49
+ def clear(stat)
50
+ redis.del("stat:#{stat}")
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,24 @@
1
+ # require 'resque/tasks'
2
+ # will give you the resque tasks
3
+
4
+ namespace :resque do
5
+ desc "Start a Resque Ranger"
6
+ task :work do
7
+ Rake::Task['resque:setup'].invoke rescue nil
8
+
9
+ worker = nil
10
+ queues = (ENV['QUEUES'] || ENV['QUEUE']).to_s.split(',')
11
+
12
+ begin
13
+ worker = Resque::Worker.new(*queues)
14
+ worker.verbose = ENV['LOGGING'] || ENV['VERBOSE']
15
+ worker.very_verbose = ENV['VVERBOSE']
16
+ rescue Resque::NoQueueError
17
+ abort "set QUEUE env var, e.g. $ QUEUE=critical,high rake resque:work"
18
+ end
19
+
20
+ puts "*** Starting worker #{worker}"
21
+
22
+ worker.work(ENV['INTERVAL'] || 5) # interval, will block
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module Resque
2
+ Version = '1.1.0'
3
+ end