resque-scheduler-web 0.0.1 → 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.
- checksums.yaml +4 -4
- data/.gitignore +3 -3
- data/.rubocop.yml +1 -0
- data/.travis.yml +11 -0
- data/README.md +8 -2
- data/Rakefile +10 -1
- data/app/assets/javascripts/resque_web/plugins/resque_scheduler/application.js +0 -0
- data/app/assets/stylesheets/resque_web/plugins/resque_scheduler/application.css +3 -0
- data/app/controllers/resque_web/plugins/resque_scheduler/delayed_controller.rb +9 -1
- data/app/controllers/resque_web/plugins/resque_scheduler/schedules_controller.rb +7 -1
- data/app/helpers/resque_web/plugins/resque_scheduler/delayed_helper.rb +9 -0
- data/app/helpers/resque_web/plugins/resque_scheduler/schedules_helper.rb +29 -1
- data/app/models/resque_web/plugins/resque_scheduler/job_finder.rb +15 -9
- data/app/models/resque_web/plugins/resque_scheduler/job_finder/working_job_finder.rb +22 -5
- data/app/views/resque_web/plugins/resque_scheduler/delayed/index.erb +1 -1
- data/lib/resque/scheduler/web.rb +1 -1
- data/lib/resque/scheduler/web/version.rb +1 -1
- data/lib/resque_web/plugins/resque_scheduler/engine.rb +10 -6
- data/resque-scheduler-web.gemspec +10 -5
- data/spec/controllers/delayed_controller_spec.rb +10 -18
- data/spec/controllers/schedules_controller_spec.rb +28 -21
- data/spec/dummy/app/controllers/application_controller.rb +1 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/log/test.log +5666 -0
- data/spec/features/navigation_spec.rb +1 -2
- data/spec/features/schedules/requeuing_a_job_with_parameters_spec.rb +8 -4
- data/spec/features/schedules/scheduled_jobs_page_spec.rb +8 -2
- data/spec/models/job_finder/working_job_finder_spec.rb +9 -7
- data/spec/models/job_finder_spec.rb +16 -13
- data/spec/rails_helper.rb +12 -9
- data/spec/routing/delayed_routing_spec.rb +5 -3
- data/spec/spec_helper.rb +6 -7
- data/spec/support/redis_instance.rb +13 -11
- data/spec/support/test_jobs.rb +9 -4
- metadata +68 -24
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 117651b5c62bac5f16c145b3f4aa0f6f38f3d9bc
|
4
|
+
data.tar.gz: 31af2fd0dc677d3014f097436dc1e7e2c06b577f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7205b8b5e211acac1efc24d102e34fe6cb2f7c0ff5f1a187b608dedb22c7a071577e629b4bf13e8c380e00ec184e4a833455929558d6fb8b240ded5552ec1cec
|
7
|
+
data.tar.gz: f70ea78760c27134564163b973f2a900c6ae797f8357526f5bf0bb1abfea5c33fb2a147cf8afa04f6497ce068d7898afa16edabbea8779517d0124fdde72ea14
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require: rubocop-rspec
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Resque::Scheduler::Web
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/resque-scheduler-web)
|
4
|
+
[](https://codeclimate.com/github/mattgibson/resque-scheduler-web)
|
5
|
+
[](https://codeclimate.com/github/mattgibson/resque-scheduler-web)
|
6
|
+
[](http://inch-ci.org/github/mattgibson/resque-scheduler-web)
|
7
|
+
[](https://gemnasium.com/mattgibson/resque-scheduler-web)
|
8
|
+
[](https://travis-ci.org/mattgibson/resque-scheduler-web)
|
9
|
+
|
3
10
|
This gem provides tabs in [Resque Web](https://github.com/resque/resque-web)
|
4
11
|
for managing [Resque Scheduler](https://github.com/resque/resque-scheduler). It uses the
|
5
12
|
new Rails Engine approach, rather than the old Sinatra one.
|
@@ -28,8 +35,7 @@ Web engine mounted like this in routes.rb:
|
|
28
35
|
## Running the tests
|
29
36
|
|
30
37
|
cd resque-scheduler-web
|
31
|
-
bundle exec
|
32
|
-
|
38
|
+
bundle exec rake
|
33
39
|
|
34
40
|
## Contributing
|
35
41
|
|
data/Rakefile
CHANGED
File without changes
|
@@ -5,6 +5,7 @@ module ResqueWeb
|
|
5
5
|
# application, so here, they can be run immediately, deleted from the
|
6
6
|
# queue, or rescheduled.
|
7
7
|
class DelayedController < ResqueWeb::ApplicationController
|
8
|
+
# GET /delayed
|
8
9
|
def index
|
9
10
|
@start = params[:start].to_i
|
10
11
|
@number_to_show = 20
|
@@ -12,6 +13,9 @@ module ResqueWeb
|
|
12
13
|
@timestamps = Resque.delayed_queue_peek(@start, @number_to_show)
|
13
14
|
end
|
14
15
|
|
16
|
+
# GET /delayed/jobs/:klass
|
17
|
+
# Shows us all of the jobs of this type, with these args. Accessed by
|
18
|
+
# clicking the 'All schedules' link next to a delayed job.
|
15
19
|
def jobs_klass
|
16
20
|
klass = Resque::Scheduler::Util.constantize(params[:klass])
|
17
21
|
@args = JSON.load(URI.decode(params[:args]))
|
@@ -20,10 +24,12 @@ module ResqueWeb
|
|
20
24
|
@timestamps = []
|
21
25
|
end
|
22
26
|
|
27
|
+
# POST /delayed/search
|
23
28
|
def search
|
24
29
|
@jobs = JobFinder.new(params[:search]).find_jobs
|
25
30
|
end
|
26
31
|
|
32
|
+
# POST /delayed/cancel_now
|
27
33
|
def cancel_now
|
28
34
|
klass = Resque::Scheduler::Util.constantize(params['klass'])
|
29
35
|
timestamp = params['timestamp']
|
@@ -32,11 +38,13 @@ module ResqueWeb
|
|
32
38
|
redirect_to Engine.app.url_helpers.delayed_path
|
33
39
|
end
|
34
40
|
|
41
|
+
# POST /delayed/clear
|
35
42
|
def clear
|
36
43
|
Resque.reset_delayed_queue
|
37
44
|
redirect_to Engine.app.url_helpers.delayed_path
|
38
45
|
end
|
39
46
|
|
47
|
+
# POST /delayed/queue_now
|
40
48
|
def queue_now
|
41
49
|
timestamp = params['timestamp'].to_i
|
42
50
|
if timestamp > 0
|
@@ -45,10 +53,10 @@ module ResqueWeb
|
|
45
53
|
redirect_to ResqueWeb::Engine.app.url_helpers.overview_path
|
46
54
|
end
|
47
55
|
|
56
|
+
# GET /delayed/:timestamp
|
48
57
|
def timestamp
|
49
58
|
@timestamp = params[:timestamp].to_i
|
50
59
|
end
|
51
|
-
|
52
60
|
end
|
53
61
|
end
|
54
62
|
end
|
@@ -3,10 +3,13 @@ require 'resque/scheduler/server'
|
|
3
3
|
module ResqueWeb
|
4
4
|
module Plugins
|
5
5
|
module ResqueScheduler
|
6
|
+
# Controller for the schedule. If it is dynamic, then the actions allow
|
7
|
+
# the jobs to be destroyed. Otherwise, the jobs can be manually queued
|
8
|
+
# for immediate execution.
|
6
9
|
class SchedulesController < ResqueWeb::ApplicationController
|
7
|
-
|
8
10
|
include Resque::Scheduler::Server::HelperMethods
|
9
11
|
|
12
|
+
# GET /schedule
|
10
13
|
def index
|
11
14
|
Resque.reload_schedule! if Resque::Scheduler.dynamic
|
12
15
|
jobs_in_this_env = Resque.schedule.select do |name|
|
@@ -18,6 +21,7 @@ module ResqueWeb
|
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
24
|
+
# DELETE /schedule
|
21
25
|
def destroy
|
22
26
|
if Resque::Scheduler.dynamic
|
23
27
|
job_name = params['job_name'] || params[:job_name]
|
@@ -26,6 +30,7 @@ module ResqueWeb
|
|
26
30
|
redirect_to Engine.app.url_helpers.schedules_path
|
27
31
|
end
|
28
32
|
|
33
|
+
# POST /schedule/requeue
|
29
34
|
def requeue
|
30
35
|
@job_name = params['job_name'] || params[:job_name]
|
31
36
|
config = Resque.schedule[@job_name]
|
@@ -38,6 +43,7 @@ module ResqueWeb
|
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
46
|
+
# POST /schedule/requeue_with_params
|
41
47
|
def requeue_with_params
|
42
48
|
job_name = params['job_name'] || params[:job_name]
|
43
49
|
config = Resque.schedule[job_name]
|
@@ -1,7 +1,16 @@
|
|
1
1
|
module ResqueWeb
|
2
2
|
module Plugins
|
3
3
|
module ResqueScheduler
|
4
|
+
# Helper methods for the delayed jobs UI
|
4
5
|
module DelayedHelper
|
6
|
+
# Outputs the time in a human readable way.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# format_time(Time.at(timestamp))
|
10
|
+
#
|
11
|
+
# @param t [Time]
|
12
|
+
# @return [String] A string in this format: 2015-04-12 12:27:05 +0100
|
13
|
+
#
|
5
14
|
def format_time(t)
|
6
15
|
t.strftime('%Y-%m-%d %H:%M:%S %z')
|
7
16
|
end
|
@@ -1,16 +1,31 @@
|
|
1
1
|
module ResqueWeb
|
2
2
|
module Plugins
|
3
3
|
module ResqueScheduler
|
4
|
+
# Helper methods for the schedule UI
|
4
5
|
module SchedulesHelper
|
6
|
+
# Tells us whether this job is scheduled for e.g. the production env.
|
7
|
+
# Jobs for other environments may be in Redis but should be ignored.
|
8
|
+
#
|
9
|
+
# @param [String] name
|
10
|
+
# @return [true, false]
|
5
11
|
def scheduled_in_this_env?(name)
|
6
12
|
return true if Resque.schedule[name]['rails_env'].nil?
|
7
13
|
rails_env(name).split(/[\s,]+/).include?(Resque::Scheduler.env)
|
8
14
|
end
|
9
15
|
|
16
|
+
# Returns the Rails env for the Resque schedule
|
17
|
+
#
|
18
|
+
# @param [String] name
|
19
|
+
# @return [String]
|
10
20
|
def rails_env(name)
|
11
21
|
Resque.schedule[name]['rails_env']
|
12
22
|
end
|
13
23
|
|
24
|
+
# Outputs a human readable string showing the schedule for a job when it
|
25
|
+
# it configured for every X interval.
|
26
|
+
#
|
27
|
+
# @param [Array] every
|
28
|
+
# @return [String]
|
14
29
|
def schedule_interval_every(every)
|
15
30
|
every = [*every]
|
16
31
|
s = 'every: ' << every.first
|
@@ -24,6 +39,11 @@ module ResqueWeb
|
|
24
39
|
s << meta.join(', ') << ')'
|
25
40
|
end
|
26
41
|
|
42
|
+
# Outputs a human readable string for the UI, showing when the job is
|
43
|
+
# scheduled.
|
44
|
+
#
|
45
|
+
# @param [Hash] config Config hash for one job
|
46
|
+
# @return [String]
|
27
47
|
def schedule_interval(config)
|
28
48
|
if config['every']
|
29
49
|
schedule_interval_every(config['every'])
|
@@ -34,6 +54,10 @@ module ResqueWeb
|
|
34
54
|
end
|
35
55
|
end
|
36
56
|
|
57
|
+
# Retrieves the class name of the job from the job config and returns it
|
58
|
+
#
|
59
|
+
# @param [Hash] config
|
60
|
+
# @return [String]
|
37
61
|
def schedule_class(config)
|
38
62
|
if config['class'].nil? && !config['custom_job_class'].nil?
|
39
63
|
config['custom_job_class']
|
@@ -42,9 +66,13 @@ module ResqueWeb
|
|
42
66
|
end
|
43
67
|
end
|
44
68
|
|
69
|
+
# Returns the name of the queue that a given class uses.
|
70
|
+
#
|
71
|
+
# @param [String] class_name
|
72
|
+
# @return [String]
|
45
73
|
def queue_from_class_name(class_name)
|
46
74
|
Resque.queue_from_class(
|
47
|
-
|
75
|
+
Resque::Scheduler::Util.constantize(class_name)
|
48
76
|
)
|
49
77
|
end
|
50
78
|
end
|
@@ -4,14 +4,19 @@ module ResqueWeb
|
|
4
4
|
# This class exists to find jobs which match a search term. They may be
|
5
5
|
# being processed, in the queue, or delayed.
|
6
6
|
class JobFinder
|
7
|
-
|
7
|
+
# The search term that the user entered.
|
8
8
|
attr_accessor :search_term
|
9
9
|
|
10
|
+
# @param [String] search_term
|
10
11
|
def initialize(search_term = nil)
|
11
12
|
@search_term = search_term || ''
|
12
13
|
@search_term.downcase!
|
13
14
|
end
|
14
15
|
|
16
|
+
# Finds all jobs that match the search term supplied when the class was
|
17
|
+
# initialized.
|
18
|
+
#
|
19
|
+
# @return [Array]
|
15
20
|
def find_jobs
|
16
21
|
return [] if search_term.empty?
|
17
22
|
results = []
|
@@ -20,13 +25,15 @@ module ResqueWeb
|
|
20
25
|
results + queued_jobs_where_class_name_matches_search_term
|
21
26
|
end
|
22
27
|
|
28
|
+
protected
|
29
|
+
|
23
30
|
def working_jobs_where_class_name_contains_search_term
|
24
31
|
WorkingJobFinder.new(search_term).find_jobs
|
25
32
|
end
|
26
33
|
|
27
34
|
def delayed_jobs_where_class_name_contains_search_term
|
28
|
-
delayed_job_timestamps.inject([]) do |
|
29
|
-
|
35
|
+
delayed_job_timestamps.inject([]) do |jobs, timestamp|
|
36
|
+
jobs + delayed_jobs_for_timestamp_that_match_search_term(timestamp)
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
@@ -67,15 +74,14 @@ module ResqueWeb
|
|
67
74
|
end
|
68
75
|
|
69
76
|
def queued_jobs_from_queue(queue)
|
70
|
-
|
71
|
-
if
|
72
|
-
|
77
|
+
jobs = Resque.peek(queue, 0, Resque.size(queue))
|
78
|
+
if jobs.is_a? Array
|
79
|
+
jobs
|
73
80
|
else
|
74
|
-
[
|
81
|
+
[jobs]
|
75
82
|
end
|
76
83
|
end
|
77
|
-
|
78
84
|
end
|
79
85
|
end
|
80
86
|
end
|
81
|
-
end
|
87
|
+
end
|
@@ -4,15 +4,32 @@ module ResqueWeb
|
|
4
4
|
class JobFinder
|
5
5
|
# This class finds working jobs that Resque is currently processing
|
6
6
|
class WorkingJobFinder
|
7
|
-
|
7
|
+
# The terms that the user entered.
|
8
8
|
attr_accessor :search_term
|
9
9
|
|
10
|
+
# The search term will be used to match against the class name of any
|
11
|
+
# jobs that are currently being processed by any of the workers.
|
12
|
+
#
|
13
|
+
# @param search_term [String]
|
10
14
|
def initialize(search_term)
|
11
15
|
@search_term = search_term
|
12
16
|
end
|
13
17
|
|
18
|
+
# Finds all jobs that match the search term provided when the class
|
19
|
+
# was instantiated.
|
20
|
+
#
|
21
|
+
# [
|
22
|
+
# {
|
23
|
+
# 'class' => 'SomeClass',
|
24
|
+
# 'queue' => 'some_queue',
|
25
|
+
# 'where_at' => 'working'
|
26
|
+
# }
|
27
|
+
# ]
|
28
|
+
#
|
29
|
+
# @return [Array] Returns an array of hashes.
|
30
|
+
#
|
14
31
|
def find_jobs
|
15
|
-
workers_with_jobs_that_match_search_term.
|
32
|
+
workers_with_jobs_that_match_search_term.map do |w|
|
16
33
|
w.job['payload'].merge(
|
17
34
|
'queue' => w.job['queue'],
|
18
35
|
'where_at' => 'working'
|
@@ -20,6 +37,8 @@ module ResqueWeb
|
|
20
37
|
end
|
21
38
|
end
|
22
39
|
|
40
|
+
protected
|
41
|
+
|
23
42
|
def workers_with_jobs_that_match_search_term
|
24
43
|
all_working_jobs.select do |w|
|
25
44
|
w.job &&
|
@@ -28,8 +47,6 @@ module ResqueWeb
|
|
28
47
|
end
|
29
48
|
end
|
30
49
|
|
31
|
-
protected
|
32
|
-
|
33
50
|
def all_working_jobs
|
34
51
|
[*Resque.working]
|
35
52
|
end
|
@@ -37,4 +54,4 @@ module ResqueWeb
|
|
37
54
|
end
|
38
55
|
end
|
39
56
|
end
|
40
|
-
end
|
57
|
+
end
|
data/lib/resque/scheduler/web.rb
CHANGED
@@ -3,16 +3,12 @@ require 'resque_web'
|
|
3
3
|
module ResqueWeb
|
4
4
|
module Plugins
|
5
5
|
module ResqueScheduler
|
6
|
+
# Main engine class for the Resque Scheduler Web plugin.
|
6
7
|
class Engine < ::Rails::Engine
|
7
8
|
isolate_namespace ResqueWeb::Plugins::ResqueScheduler
|
8
|
-
|
9
|
-
# paths['app'] << 'app'
|
10
|
-
# paths['app/helpers'] << 'app/helpers'
|
11
|
-
# paths['app/views'] << 'app/views'
|
12
|
-
# paths['app/controllers'] << 'app/controllers'
|
13
|
-
# paths['app/models'] << 'app/models'
|
14
9
|
end
|
15
10
|
|
11
|
+
# Draws the routes for the engine.
|
16
12
|
Engine.routes do
|
17
13
|
get 'schedule', to: 'schedules#index', as: 'schedules'
|
18
14
|
post 'schedule/requeue', to: 'schedules#requeue', as: 'requeue'
|
@@ -32,10 +28,18 @@ module ResqueWeb
|
|
32
28
|
post '/delayed/clear', to: 'delayed#clear', as: 'clear'
|
33
29
|
end
|
34
30
|
|
31
|
+
# provides the path where the engine will live. This is appended after
|
32
|
+
# the main resque-web path.
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
35
|
def self.engine_path
|
36
36
|
'/scheduler'
|
37
37
|
end
|
38
38
|
|
39
|
+
# Tells Resque web what extra tabs to ass to the main navigation at the
|
40
|
+
# top of the resque-web interface.
|
41
|
+
#
|
42
|
+
# @return [Array]
|
39
43
|
def self.tabs
|
40
44
|
[
|
41
45
|
{
|