resque-telework 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ <% @subtabs= my_substabs %>
2
+ <h1>Miscellaneous Stuff</h1>
3
+
4
+
5
+ Telework is a plugin for Resque
6
+ <br><br>
7
+ Please refer to <a href="https://github.com/gip/resque-telework">https://github.com/gip/resque-telework</a> for further information
8
+
9
+ <br><br>
10
+ <table>
11
+ <tr><th width="100">Telework version</th><td width="500"><%= Resque::Plugins::Telework::Version %></td></tr>
12
+ <tr><th width="100">Redis interface version</th><td width="500"><%= Resque::Plugins::Telework::RedisInterfaceVersion %></td></tr>
13
+ <tr><th width="100">Number of keys in Redis</th><td width="500"><%= redis.nb_keys %></td></tr>
14
+ <tr><th width="100">Redis key prefix</th><td width="500"><%= redis.key_prefix %></td></tr>
15
+ <tr><th width="100">Number of running workers</th><td width="500"><%= c=0; redis.hosts.each { |h| c+= redis.workers(h).length }; c %></td></tr>
16
+ </table>
17
+ <br><br>
18
+ <h1>Configuration</h1><br>
19
+ <table>
20
+ <tr><th width="100">Configuration</th><td width="500"><%= redis.configuration %></td></tr>
21
+ </table>
@@ -0,0 +1,25 @@
1
+ <h1>Revision <%= @revision%></h1>
2
+
3
+ <% res= {}
4
+ redis.hosts.each do |h|
5
+ redis.revisions(h).each do |r|
6
+ res[h]= r if r['revision']==@revision
7
+ end
8
+ end
9
+ %>
10
+
11
+ <% if res.empty? %>
12
+ <br>This revision is unknown
13
+ <% else %>
14
+ <br>
15
+ <table>
16
+ <tr><th width="100">Revision</th><td width="100"><%= res[res.keys[0]]['revision'] %></td></tr>
17
+ <tr><th>Revision (short)</th><td><%= res[res.keys[0]]['revision_small'] %></td></tr>
18
+ <tr><th width="100">Revision date</th><td width="100"><%= redis.fmt_date(res[res.keys[0]]['revision_date']) %></td></tr>
19
+ <tr><th>Link</th><td><% l=res[res.keys[0]]['revision_link']%> <a href="<%= l%>"><%= l %></a></td></tr>
20
+ <tr><th>Deployed on</th><td><%= res.keys * ", " %></a></td></tr>
21
+ <tr><th>Commit log</th><td><%= redis.text_to_html(res[res.keys[0]]['revision_info'])%></a></td></tr>
22
+ </table>
23
+
24
+
25
+ <% end %>
@@ -0,0 +1,35 @@
1
+ <% object= @daemon ? "#{@host} daemon" : "worker #{@worker}" %>
2
+
3
+ <% if @kill %>
4
+ <h1>Killing <%= object %></h1>
5
+ <% else %>
6
+ <h1>Stopping <%= object %></h1>
7
+ <% end %>
8
+ <br>
9
+
10
+ <% if @host %>
11
+ A command to <%= @kill ? "kill" : "stop" %> <%= object %> has been send to host <%= @host%>
12
+ <% else %>
13
+ Worker not found
14
+ <% end %>
15
+
16
+ <% if @host %>
17
+ <% unless @kill %>
18
+ <br><br><% id= @worker %>
19
+
20
+ If that doesn't work, you may just kill it<br>
21
+ <% unless @daemon %>
22
+ <form id="kill<%=id%>" name="kill<%=id%>" method="post" action="/resque/telework_killit/<%=id%>" ><input type="submit" value= <%="\"Kill #{id}\"" %> >
23
+ </form>
24
+ <% else %>
25
+ <form id="kill" name="kill" method="post" action="/resque/telework_killitd/<%=@host%>" ><input type="submit" value= <%="\"Kill\"" %> >
26
+ </form>
27
+ <% end %>
28
+
29
+ <% end %>
30
+ <% end %>
31
+
32
+ <br><br>
33
+ <a href="/resque/telework">Return to main Telework page</a>
34
+
35
+
@@ -0,0 +1,262 @@
1
+ <% @subtabs= my_substabs %>
2
+ <% if @refresh %>
3
+ <META HTTP-EQUIV="refresh" CONTENT="<%= @refresh%>">
4
+ <% end %>
5
+
6
+
7
+ <script language="javascript" type="text/javascript">
8
+ function hostlist(index) {
9
+ document.startform.rev_filter.options.length = 0;
10
+ switch(index) {
11
+ <% for host in redis.hosts %>
12
+ <%= "case'#{host}':" %>
13
+ <% i= 0 %>
14
+ <% for rev in redis.revisions(host) %>
15
+ <%= "document.startform.rev_filter.options[#{i}]= new Option('#{rev['revision_small']} from #{redis.fmt_date(rev['revision_date'])}', '#{rev['revision']} #{rev['revision_small']}' );" %>
16
+ <% i+= 1 %>
17
+ <% end %> break;
18
+ <% end %>
19
+ };
20
+ return true;
21
+ };
22
+ function queuelist(index) {
23
+ if(index != "(other)") {
24
+ document.startform.queue_text.value= "";
25
+ }
26
+ return true;
27
+ };
28
+ function queuetext(val) {
29
+ if(val!="") {
30
+ document.startform.queue_filter.selectedIndex= 0;
31
+ }
32
+ };
33
+ function action(val) {
34
+ var params = val.split(",");
35
+ var url = "";
36
+ switch(params[0]) {
37
+ case "start":
38
+ url = "/start?task="+params[1]+"&host="+params[2]+"&rev="+document.getElementById("rev_filter_"+params[1]).value;
39
+ break;
40
+ case "pause":
41
+ url = "/pause?task="+params[1]+"&host="+params[2];
42
+ break;
43
+ case "cont":
44
+ url = "/pause?cont=true&task="+params[1]+"&host="+params[2];
45
+ break;
46
+ case "stop":
47
+ url = "/stop?kill=false&task="+params[1]+"&host="+params[2];
48
+ break;
49
+ case "kill":
50
+ url = "/stop?kill=true&task="+params[1]+"&host="+params[2];
51
+ break;
52
+ case "delete":
53
+ url = "/delete?task="+params[1]+"&host="+params[2];
54
+ break;
55
+ default:
56
+ return true;
57
+ }
58
+ var form = document.createElement("form");
59
+ form.setAttribute("method", "post");
60
+ form.setAttribute("action", "/resque/telework"+url);
61
+ document.body.appendChild(form);
62
+ form.submit();
63
+ };
64
+ $(document).ready(function() {
65
+ document.startform.queue_filter.selectedIndex= 1;
66
+ hostlist($('#host_filter').val());
67
+ queuelist($('#queue_filter').val());
68
+ });
69
+ </script>
70
+
71
+ <% redis.reconcile %>
72
+
73
+ <% notes= redis.notes_pop %>
74
+ <% if notes.length>0 %>
75
+
76
+ <h1>Notes</h1>
77
+ <table>
78
+ <tr>
79
+ <th>User</th>
80
+ <th>Date</th>
81
+ <th>Note</th>
82
+ <th>Action</th>
83
+ </tr>
84
+ <% for note,id in notes.each_with_index %>
85
+ <tr>
86
+ <td><%= note['user'] %></td>
87
+ <td><%= "#{redis.fmt_date(note['date'], true)}" %></td>
88
+ <td><%= note['note'] %></td>
89
+ <td>
90
+ <form id="deln" name="deln" method="post" action="/resque/telework_del_note/<%= id %>" ><input type="submit" value= "Delete" /></form>
91
+ </td>
92
+ </tr>
93
+ <% end %>
94
+ </table>
95
+ <br>
96
+ <% end %>
97
+
98
+ <% if @scheduling %>
99
+
100
+ <h1>Starting Workers</h1>
101
+ <br>
102
+
103
+ <div class="clearfix">
104
+ <div class="control_panel sub_header">
105
+ <form id="startform" name="startform" method="post" action="/resque/telework/start_task" >
106
+ <span class="host_filter">
107
+ Host: <%= generic_filter("host_filter", "h", redis.hosts,
108
+ "onchange=\"javascript: hostlist(this.options[this.selectedIndex].value);\"") %>
109
+ </span>
110
+ <span class="queue_filter">
111
+ Queue: <%= generic_filter("queue_filter", "q", ["(other)"] + Resque.redis.smembers('queues').sort << "*",
112
+ "onchange=\"javascript: queuelist(this.options[this.selectedIndex].value);\"") %>
113
+ Queue: <input id="queue_text" type="text" name="qmanual" onkeyup="javascript: queuetext(this.value);" />
114
+ </span>
115
+ <span class="count_filter">
116
+ Count: <%= generic_filter("count_filter", "c", ['1', '2', '3', '4', '5', '6', '7', '8'] ) %>
117
+ </span>
118
+ <span class="rev_filter">
119
+ Revision: <select id="rev_filter" name="r">
120
+ </select>
121
+ </span>
122
+ <span class="env_filter">
123
+ Environment: <%= generic_filter("env_filter", "e", ['(default)', 'production', 'staging', 'development', 'test'] ) %>
124
+ </select>
125
+ </span>
126
+ <input type="submit" value="Start" />
127
+ </form>
128
+ </div>
129
+ </div><br><br><br><br>
130
+ <% end %>
131
+
132
+ <br>
133
+ <% if @scheduling %>
134
+ <h1>Adding Notes</h1>
135
+ <br>
136
+ <div class="clearfix">
137
+ <div class="control_panel sub_header">
138
+ <form id="noting" name="noting" method="post" action="/resque/telework/add_note">
139
+ <span class="note_user">User<input id="note_user" type="text" name="note_user"/></span>
140
+ <span class="note_text">Note<input id="note_text" type="text" size="100" name="note_text"/></span>
141
+ <span class="note_submit"><input type="submit" value="Add"/></span>
142
+ </form>
143
+ </div></div>
144
+ <br><br><br><br>
145
+ <% end %>
146
+
147
+ <h1>Hosts, Revisions, Tasks and Workers</h1>
148
+ <table>
149
+ <tr>
150
+ <th>Host</th>
151
+ <th>Daemon</th>
152
+ <th>Revisions</th>
153
+ <th>Tasks and Workers</th>
154
+ </tr>
155
+ <% for host, status, info in redis.daemons_state %>
156
+ <tr>
157
+ <td><center><%= host%>
158
+ <% if 'Alive'==status && info['cpu_load_1mins'] %>
159
+ <br><%= "(%.2f%% cpu)" % (100*info['cpu_load_1mins']) %></center>
160
+ <% end %>
161
+ </td>
162
+ <% if 'Alive'==status %>
163
+ <td> <table><tr><td><%= "Alive (v#{info['version']})" %></td></tr>
164
+ <tr><td>
165
+ <form id="stopd" name="stopd" method="post" action="/resque/telework_stopitd/<%= host %>" ><input type="submit" value= <%="\"Stop\""%> /></form>
166
+ </td></tr>
167
+ </table>
168
+ </td>
169
+ <% else %>
170
+ <td><%= status%></td>
171
+ <% end %>
172
+ <td><%= redis.revisions(host).length %> revision(s) installed
173
+ <table><tr>
174
+ <th>Revision</th>
175
+ <th>Branch</th>
176
+ <th>Deployed</th>
177
+ </tr>
178
+ <% for rev in redis.revisions(host) %>
179
+ <tr>
180
+ <td><a href= <%= "/resque/telework/revision/#{rev['revision']}" %> ><%= "#{rev['revision_small']}" %></a></td>
181
+ <td><%= "#{rev['revision_branch']}" %></td>
182
+ <td><%= "#{redis.fmt_date(rev['revision_deployement_date'], true)}" %></td>
183
+ </tr>
184
+ <%end%>
185
+ </table>
186
+ </td>
187
+ <td><%= redis.tasks(host).length%> task(s)
188
+ <table><tr>
189
+ </tr><th>Task</th>
190
+ <th>Status</th>
191
+ <th>Queue(s)</th>
192
+ <th>Count</th>
193
+ <th>Revision</th>
194
+ <th>Action</th>
195
+ <th>Worker(s)</th>
196
+ <tr>
197
+ <% for id, info in redis.tasks(host) %>
198
+ <% status= info['worker_status'] %>
199
+ <% status= 'Stopped' if status.blank? %>
200
+ <% running= status!='Stopped' %>
201
+ <% paused= status=='Paused' %>
202
+ <td><%= "<a hreftbd=\"/resque/telework/task/#{host}/#{id}\">#{id}</a>" %>
203
+ </td><td><%= "#{status}" %>
204
+ </td><td><%= "#{info['queue'].gsub(/,/,'<br/>')}" %>
205
+ </td><td><%= "#{info['worker_count']}" %>
206
+ </td><td><% if running %><a href= <%= "/resque/telework/revision/#{info['revision']}" %> ><%= "#{info['revision_small']}" %></a>
207
+ <% else %> <select id= <%= "\"rev_filter_#{id}\"" %> name="r"/>
208
+ <% for rev in redis.revisions(host) %>
209
+ <option value=<%= "\"#{rev['revision']},#{rev['revision_small']}\"" %> ><%= rev['revision_small'] %></option>
210
+ <% end %>
211
+ </select>
212
+ <% end %>
213
+ </td><td>
214
+ <select id="action" name="a" onchange="javascript: action(this.options[this.selectedIndex].value);" >
215
+ <option select="selected" value="select">Select</option>
216
+ <option <%= 'disabled="disabled"' if running %> value=<%= "\"start,#{id},#{host}\"" %> >Start worker</option>
217
+ <option <%= 'disabled="disabled"' unless running %> value=<%= "\"stop,#{id},#{host}\"" %> >Stop worker</option>
218
+ <option <%= 'disabled="disabled"' unless running %> value=<%= "\"kill,#{id},#{host}\"" %> >Kill worker</option>
219
+ <option <%= 'disabled="disabled"' if (!running || paused) %> value=<%= "\"pause,#{id},#{host}\"" %> >Pause worker</option>
220
+ <option <%= 'disabled="disabled"' unless paused %> value=<%= "\"cont,#{id},#{host}\"" %> >Resume worker</option>
221
+ <option <%= 'disabled="disabled"' if running %> value=<%= "\"delete,#{id},#{host}\"" %> >Delete</option>
222
+ </select>
223
+ </td><td align="center"><p align="center"><font size="1">
224
+ <% info['worker_id'].zip(info['worker_pid']) do |id,pid| %>
225
+ <%= "<a href=\"/resque/telework/worker/#{host}/#{id}\">Worker #{id}</a>" if running %><br/>
226
+ <font size=1><% l= "#{host}:#{pid}" %><%= "<a href=\"/resque/workers/#{l}:#{info['queue']}\">#{l}</a>" if running %></font><br/>
227
+ <% end %>
228
+ </font></p>
229
+ </td></tr>
230
+ <%end%>
231
+ </table>
232
+ </td>
233
+ </tr>
234
+ <% end %>
235
+ </table>
236
+
237
+ <br>
238
+ <% if @status_messages %>
239
+ <h1>Status Messages</h1>
240
+ <table>
241
+ <tr>
242
+ <th>Host</th>
243
+ <th>Severity</th>
244
+ <th>Date</th>
245
+ <th>Message</th>
246
+ </tr>
247
+ <% for info in redis.statuses(@status_messages) %>
248
+ <% c= info['severity']=='Error' ? "bgcolor=\"#ff0000\"" : "" %>
249
+ <tr>
250
+ <td <%= c %>><%= info['host'] %></td>
251
+ <td <%= c %>><%= info['severity'] %></td>
252
+ <td <%= c %>><%= redis.fmt_date(info['date']) %></td>
253
+ <td <%= c %>><%= info['message'] %></td>
254
+ </tr>
255
+ <% end %>
256
+ </table>
257
+
258
+ <%end%>
259
+
260
+
261
+
262
+ </div>
@@ -0,0 +1,38 @@
1
+ <h1>Worker <%= @worker%></h1>
2
+
3
+ <% worker= redis.workers_by_id(@host, @worker) %>
4
+ <% if worker %>
5
+
6
+ Running on host <%= @host %>
7
+ <br><br>
8
+ Link: <% l= "#{@host}:#{worker['pid']}" %><%= "<a href=\"/resque/workers/#{l}:#{worker['environment']['QUEUE']}\">#{l}</a>" %>
9
+ <br><br>
10
+ TODO: better formatting for table below!
11
+ <table>
12
+ <% for k in worker.keys %>
13
+ <tr><th width="30"><%= k %></th><td width="600"><%= worker[k] %></td></tr>
14
+ <% end %>
15
+ </table>
16
+
17
+ <br>
18
+
19
+ <h1>Logs</h1>
20
+ <% log= redis.logs_by_id(@host, @worker) %>
21
+ <br>
22
+ <% if log %>
23
+ <%= "Logs as of #{redis.fmt_date(log['date'])}"%>
24
+
25
+ <table>
26
+ <tr><th width="30">STDERR</th><td width="600"><%= redis.text_to_html(log['log_stderr']) %></td></tr>
27
+ <tr><th width="30">STDOUT</th><td width="600"><%= redis.text_to_html(log['log_stdout']) %></td></tr>
28
+ </table>
29
+
30
+
31
+ <% else %>
32
+ Logs are not available
33
+ <% end %>
34
+
35
+
36
+ <% else %>
37
+ Worker not found
38
+ <% end %>
@@ -0,0 +1,220 @@
1
+ module Resque
2
+ module Plugins
3
+ module Telework
4
+ module Server
5
+
6
+ require 'erb'
7
+
8
+ VIEW_PATH = File.join(File.dirname(__FILE__), 'server', 'views')
9
+ PUBLIC_PATH = File.join(File.dirname(__FILE__), 'server', 'public')
10
+
11
+ def self.registered( app )
12
+ appn= 'Telework'
13
+
14
+ # This helpers adds stuff to the app closure
15
+ app.helpers do
16
+ @@myredis= TeleworkRedis.new
17
+ def redis
18
+ @@myredis
19
+ end
20
+ def my_substabs
21
+ ["Overview", "Start", "Misc"]
22
+ end
23
+ def my_show(page, layout = true)
24
+ response["Cache-Control"] = "max-age=0, private, must-revalidate"
25
+ begin
26
+ erb(File.read(File.join(VIEW_PATH, "#{page}.erb")), {:layout => layout}, :resque => Resque)
27
+ rescue Errno::ECONNREFUSED
28
+ erb :error, {:layout => false}, :error => "Can't connect to Redis! (#{Resque.redis_id})"
29
+ end
30
+ end
31
+ def generic_filter(id, name, list, more= "")
32
+ html = "<select id=\"#{id}\" name=\"#{name}\" #{more}>"
33
+ #html += "<option value=\"\">-</option>"
34
+ value= list[0]
35
+ list.each do |k|
36
+ selected = k == value ? 'selected="selected"' : ''
37
+ html += "<option #{selected} value=\"#{k}\">#{k}</option>"
38
+ end
39
+ html += "</select>"
40
+ end
41
+
42
+ end
43
+
44
+ app.get "/#{appn.downcase}" do
45
+ redirect "/resque/#{appn.downcase}/Overview"
46
+ end
47
+
48
+ app.get "/#{appn.downcase}/Overview" do
49
+ @status_messages= 100
50
+ @refresh= 10
51
+ @scheduling= nil
52
+ my_show appn.downcase
53
+ end
54
+
55
+ app.get "/#{appn.downcase}/Start" do
56
+ @status_messages= 100
57
+ @scheduling= true
58
+ my_show appn.downcase
59
+ end
60
+
61
+ app.get "/#{appn.downcase}/Misc" do
62
+ my_show 'misc'
63
+ end
64
+
65
+ app.get "/#{appn.downcase}/revision/:revision" do
66
+ @revision= params[:revision]
67
+ my_show 'revision'
68
+ end
69
+
70
+ app.get "/#{appn.downcase}/worker/:host/:worker" do
71
+ @worker= params[:worker]
72
+ @host= params[:host]
73
+ my_show 'worker'
74
+ end
75
+
76
+ app.get "/#{appn.downcase}/config" do
77
+ content_type :json
78
+ redis.configuration
79
+ end
80
+
81
+ app.post "/#{appn.downcase}_stopit/:worker" do
82
+ @worker= params[:worker]
83
+ @host= nil
84
+ @daemon= nil
85
+ redis.hosts.each do |h|
86
+ redis.workers(h).each do |id, info|
87
+ @host= h if id==@worker # TODO: break nested loops
88
+ end
89
+ end
90
+ redis.cmds_push( @host, { 'command' => 'stop_worker', 'worker_id'=> @worker } ) if @host
91
+ my_show 'stopit'
92
+ end
93
+
94
+ app.post "/#{appn.downcase}_stopitd/:host" do
95
+ # Todo - check that the host indeed exists
96
+ @host= params[:host]
97
+ @daemon= true
98
+ redis.cmds_push( @host, { 'command' => 'stop_daemon' } )
99
+ my_show 'stopit'
100
+ end
101
+
102
+ app.post "/#{appn.downcase}_killitd/:host" do
103
+ # Todo - check that the host indeed exists
104
+ @host= params[:host]
105
+ @daemon= true
106
+ @kill= true
107
+ redis.cmds_push( @host, { 'command' => 'kill_daemon' } )
108
+ my_show 'stopit'
109
+ end
110
+
111
+ app.post "/#{appn.downcase}_killit/:worker" do
112
+ @worker= params[:worker]
113
+ @host= nil
114
+ @kill= true
115
+ redis.hosts.each do |h|
116
+ redis.workers(h).each do |id, info|
117
+ @host= h if id==@worker # TODO: break nested loops
118
+ end
119
+ end
120
+ redis.cmds_push( @host, { 'command' => 'kill_worker', 'worker_id'=> @worker } ) if @host
121
+ my_show 'stopit'
122
+ end
123
+
124
+ app.post "/#{appn.downcase}/add_note" do
125
+ @user= params[:note_user]
126
+ @date= Time.now
127
+ @note= params[:note_text]
128
+ redis.notes_push({ 'user'=> @user, 'date'=> @date, 'note' => @note })
129
+ redirect "/resque/#{appn.downcase}"
130
+ end
131
+
132
+ app.post "/#{appn.downcase}_del_note/:note" do
133
+ @note_id= params[:note]
134
+ redis.notes_del(@note_id)
135
+ redirect "/resque/#{appn.downcase}"
136
+ end
137
+
138
+ # Start a task
139
+ app.post "/telework/start_task" do
140
+ @host= params[:h]
141
+ @queue= params[:q]
142
+ @qmanual= params[:qmanual]
143
+ @count= params[:c]
144
+ @rev= params[:r].split(' ')
145
+ @env= params[:e]
146
+ @q= @qmanual.blank? ? @queue : @qmanual
147
+ id= redis.unique_id.to_s
148
+ redis.tasks_add( @host , id, { 'revision' => @rev[0], 'revision_small' => @rev[1],
149
+ 'task_id' => id, 'worker_count' => @count,
150
+ 'rails_env' => @env, 'queue' => @q,
151
+ 'exec' => "bundle exec rake resque:work --trace",
152
+ 'worker_id' => [], 'worker_status' => 'Stopped',
153
+ 'log_snapshot_period' => 30,
154
+ 'log_snapshot_lines' => 40 } )
155
+ redirect "/resque/#{appn.downcase}"
156
+ end
157
+
158
+ app.post "/#{appn.downcase}/delete" do
159
+ @task_id= params[:task]
160
+ @host= params[:host]
161
+ redis.tasks_rem( @host, @task_id )
162
+ redirect "/resque/#{appn.downcase}"
163
+ end
164
+
165
+ # Start workers
166
+ app.post "/#{appn.downcase}/start" do
167
+ @task_id= params[:task]
168
+ @host= params[:host]
169
+ @rev= params[:rev].split(',')
170
+ @task= redis.tasks_by_id(@host, @task_id)
171
+ count= @task['worker_count'] || 1
172
+ id= []
173
+ for i in 1..count.to_i do
174
+ w= @task
175
+ w['worker_id']= redis.unique_id.to_s
176
+ id << w['worker_id']
177
+ w['worker_status']= 'Starting'
178
+ w['revision']= @rev[0]
179
+ w['revision_small']= @rev[1]
180
+ w['command']= 'start_worker'
181
+ w['task_id']= @task_id
182
+ redis.cmds_push( @host, w )
183
+ end
184
+ @task['worker_id']= id
185
+ redis.tasks_add( @host, @task_id, @task )
186
+ redirect "/resque/#{appn.downcase}"
187
+ end
188
+
189
+ app.post "/#{appn.downcase}/pause" do
190
+ @task_id= params[:task]
191
+ @host= params[:host]
192
+ @cont= params[:cont]=="true"
193
+ @task= redis.tasks_by_id(@host, @task_id)
194
+ @task['worker_id'].each do |id|
195
+ redis.cmds_push( @host, { 'command' => 'signal_worker', 'worker_id'=> id, 'action' => @cont ? 'CONT' : 'PAUSE' } )
196
+ end
197
+ redirect "/resque/#{appn.downcase}"
198
+ end
199
+
200
+ app.post "/#{appn.downcase}/stop" do
201
+ @task_id= params[:task]
202
+ @host= params[:host]
203
+ @kill= params[:kill]=="true"
204
+ @task= redis.tasks_by_id(@host, @task_id)
205
+ @task['worker_id'].each do |id|
206
+ redis.cmds_push( @host, { 'command' => 'signal_worker', 'worker_id'=> id, 'action' => @kill ? 'KILL' : 'QUIT' } )
207
+ end
208
+ redirect "/resque/#{appn.downcase}"
209
+ end
210
+
211
+ app.tabs << appn
212
+
213
+ end
214
+
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ Resque::Server.register Resque::Plugins::Telework::Server