sidekiq-enqueuer 1.0.6 → 2.0.0.beta1
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/.travis.yml +3 -0
- data/CHANGELOG.md +27 -0
- data/README.md +45 -1
- data/Rakefile +5 -5
- data/lib/sidekiq-enqueuer.rb +1 -1
- data/lib/sidekiq/enqueuer.rb +23 -72
- data/lib/sidekiq/enqueuer/configuration.rb +51 -0
- data/lib/sidekiq/enqueuer/version.rb +1 -1
- data/lib/sidekiq/enqueuer/views/index.erb +23 -21
- data/lib/sidekiq/enqueuer/views/new.erb +39 -56
- data/lib/sidekiq/enqueuer/web_extension/helper.rb +35 -0
- data/lib/sidekiq/enqueuer/web_extension/loader.rb +36 -0
- data/lib/sidekiq/enqueuer/web_extension/params_parser.rb +48 -0
- data/lib/sidekiq/enqueuer/worker/instance.rb +50 -0
- data/lib/sidekiq/enqueuer/worker/param.rb +20 -0
- data/lib/sidekiq/enqueuer/worker/trigger.rb +51 -0
- data/sidekiq-enqueuer.gemspec +12 -12
- metadata +12 -6
- data/Changes.md +0 -18
- data/lib/sidekiq/enqueuer/web_extension.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1585a3c676060297b1cc89c7b1c554fe8b1b05d1
|
4
|
+
data.tar.gz: 004294f3a7df7865e4b6b3cfa7f2aa9f1839c808
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f956108676be7658c630fc4dd19115e9dd23ab4b434aaef81369f5680d195ca9dba7e411be5f33887fd396ecc3f4bff7efa73c89880f330a3ed9b348253a0042
|
7
|
+
data.tar.gz: 514423672fc749f515637eacd92251be9ec1169a94070adf3af6e6a0e90ab1e73915af23286645df4084c3c6a9a2883c815f74caaf819e1e3974b0c253d7ee89
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Sidekiq Enqueuer Changes
|
2
|
+
|
3
|
+
2.0.0.beta
|
4
|
+
-----------
|
5
|
+
|
6
|
+
- Added configutation option: Provides a list of Jobs to display
|
7
|
+
- Dropped support for manual 'unlock'
|
8
|
+
- Sidekiq enqueing now uses `Sidekiq::Client.enqueue_to / enqueue_to_in` to a custom queue.
|
9
|
+
- Refactor on classes and modules to bring Atomicity
|
10
|
+
|
11
|
+
|
12
|
+
1.0.6
|
13
|
+
-----------
|
14
|
+
|
15
|
+
- Jobs are sorted by name by default
|
16
|
+
|
17
|
+
|
18
|
+
1.0.4
|
19
|
+
-----------
|
20
|
+
|
21
|
+
- Support for jobs without arguments
|
22
|
+
|
23
|
+
|
24
|
+
1.0.3
|
25
|
+
-----------
|
26
|
+
|
27
|
+
- Support unlock! for sidekiq-middleware
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# Sidekiq::Enqueuer
|
2
|
+
[](https://travis-ci.org/vgarro/sidekiq-enqueuer)
|
2
3
|
|
3
4
|
A Sidekiq Web extension to enqueue/schedule job in Web UI. Support both Sidekiq::Worker and ActiveJob.
|
4
5
|
|
@@ -21,6 +22,49 @@ Edit config/initializers/sidekiq.rb, add following line
|
|
21
22
|
require 'sidekiq/enqueuer'
|
22
23
|
```
|
23
24
|
|
25
|
+
Optionally, provide a list of Jobs to display on the new tab, on a new initializer file.
|
26
|
+
Worry not, when no configuration is provided, All jobs will be displayed
|
27
|
+
|
28
|
+
```
|
29
|
+
# config/initializers/sidekiq_enqueuer_config.rb
|
30
|
+
require 'sidekiq/enqueuer'
|
31
|
+
|
32
|
+
Sidekiq::Enqueuer.configure do |config|
|
33
|
+
config.jobs = [MyAwesomeJob1, MyModule::MyAwesomeJob2]
|
34
|
+
end
|
35
|
+
|
36
|
+
```
|
37
|
+
|
38
|
+
|
39
|
+
## Notes:
|
40
|
+
|
41
|
+
### Queuing & ActiveJob support
|
42
|
+
Use default sidekiq queue adapter for Jobs including Sidekiq::Worker or Jobs inheriting from ActiveJob::base
|
43
|
+
|
44
|
+
```
|
45
|
+
ActiveJob::Base.queue_adapter = :sidekiq
|
46
|
+
```
|
47
|
+
https://github.com/mperham/sidekiq/wiki/Active-Job#active-job-setup
|
48
|
+
|
49
|
+
|
50
|
+
### Jobs action param mapping.
|
51
|
+
This gem dynamically infers the params required in the `perform` or `perform_in` action in your Job / Worker.
|
52
|
+
It is important those actions (either of them) won't hide the actual params into a single *args one.
|
53
|
+
In that case it will be impossible to infer the params for your method.
|
54
|
+
|
55
|
+
Want to verify this last line? Run this in a rails console:
|
56
|
+
```
|
57
|
+
MyJob.instance_method(:perform).parameters # change :perform for your implemented method
|
58
|
+
>> [[:req, :param1], [:opt, :param2], [:opt, :param3]] # Good output
|
59
|
+
|
60
|
+
=> [[:rest, :args], [:block, :block]] # Bad output. Params are being wrapped into a super class.
|
61
|
+
```
|
62
|
+
|
63
|
+
### Enqueuing Jobs:
|
64
|
+
|
65
|
+
For Sidekiq, enqueing is being done using `Sidekiq::Client.enqueue_to` / `enqueue_to_in`, providing Job, and queue extracted from the Job sidekiq_options hash, defaults to 'default' queue when not present.
|
66
|
+
|
67
|
+
For ActiveJob, enqueing is being done calling the very own `perform_later` instance method. Please advise your Job should respond to `perform_later` to correctly work.
|
24
68
|
|
25
69
|
## Usage
|
26
70
|
|
@@ -30,7 +74,7 @@ require 'sidekiq/enqueuer'
|
|
30
74
|
|
31
75
|

|
32
76
|
|
33
|
-
* Fill the form, click Enqueue or Schedule.
|
77
|
+
* Fill the form, click Enqueue or Schedule.
|
34
78
|

|
35
79
|
|
36
80
|
* That is it!
|
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
3
|
|
4
4
|
task :default => :test
|
5
5
|
|
6
6
|
Rake::TestTask.new do |t|
|
7
|
-
t.libs <<
|
8
|
-
t.libs <<
|
9
|
-
t.test_files = FileList[
|
7
|
+
t.libs << 'lib'
|
8
|
+
t.libs << 'test'
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
10
10
|
t.verbose = true
|
11
11
|
end
|
data/lib/sidekiq-enqueuer.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'sidekiq/enqueuer'
|
1
|
+
require 'sidekiq/enqueuer'
|
data/lib/sidekiq/enqueuer.rb
CHANGED
@@ -1,88 +1,39 @@
|
|
1
1
|
require 'sidekiq/web'
|
2
|
-
require
|
3
|
-
require 'sidekiq/enqueuer/
|
2
|
+
require 'sidekiq/enqueuer/version'
|
3
|
+
require 'sidekiq/enqueuer/configuration'
|
4
|
+
require 'sidekiq/enqueuer/worker/instance'
|
5
|
+
require 'sidekiq/enqueuer/worker/param'
|
6
|
+
require 'sidekiq/enqueuer/worker/trigger'
|
7
|
+
require 'sidekiq/enqueuer/web_extension/loader'
|
8
|
+
require 'sidekiq/enqueuer/web_extension/helper'
|
9
|
+
require 'sidekiq/enqueuer/web_extension/params_parser'
|
4
10
|
require 'sidekiq/enqueuer/railtie' if defined? ::Rails::Railtie
|
5
11
|
|
6
12
|
module Sidekiq
|
7
13
|
module Enqueuer
|
8
|
-
|
9
|
-
|
10
|
-
::Rails.application.eager_load!
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.get_job_modules
|
15
|
-
ObjectSpace.each_object(Module)
|
16
|
-
.select { |klass| has_worker_module?(klass) }
|
17
|
-
.delete_if { |klass| klass.to_s =~ /^Sidekiq::Extensions/ }
|
18
|
-
.delete_if { |klass| klass.to_s =~ /^ActiveJob::QueueAdapters/ }
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.get_job_classes
|
22
|
-
ObjectSpace.each_object(Class)
|
23
|
-
.select { |klass| is_job_class?(klass) }
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.get_jobs
|
27
|
-
return @jobs if @jobs
|
28
|
-
|
29
|
-
rails_eager_load
|
30
|
-
jobs = get_job_modules + get_job_classes
|
31
|
-
jobs = jobs.map(&:to_s).uniq.map(&:constantize)
|
32
|
-
@jobs = jobs.sort_by(&:name)
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.is_job_class?(klass)
|
36
|
-
return false if !defined?(::ActiveJob)
|
14
|
+
class << self
|
15
|
+
attr_accessor :configuration
|
37
16
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
def self.has_worker_module?(klass)
|
42
|
-
klass.included_modules.include? ::Sidekiq::Worker
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.perform_async(klass, values)
|
46
|
-
parsed_values = values_parser(values)
|
47
|
-
if is_job_class?(klass)
|
48
|
-
klass.perform_later(*parsed_values)
|
49
|
-
elsif has_worker_module?(klass)
|
50
|
-
klass.perform_async(*parsed_values)
|
17
|
+
def configuration
|
18
|
+
@configuration ||= Configuration.new
|
51
19
|
end
|
52
|
-
end
|
53
20
|
|
54
|
-
|
55
|
-
|
56
|
-
seconds = seconds_str.to_i.seconds
|
57
|
-
if is_job_class?(klass)
|
58
|
-
klass.set(wait: seconds).perform_later(*parsed_values)
|
59
|
-
elsif has_worker_module?(klass)
|
60
|
-
klass.perform_in(seconds, *parsed_values)
|
21
|
+
def configure
|
22
|
+
yield(configuration)
|
61
23
|
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.unlock!(klass, values)
|
65
|
-
parsed_values = values_parser(values)
|
66
|
-
klass.unlock!(*parsed_values)
|
67
|
-
end
|
68
24
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
if value =~ /^{/
|
74
|
-
parsed_values << YAML.load(value) rescue errors << value
|
75
|
-
else
|
76
|
-
parsed_values << value
|
25
|
+
def all_jobs
|
26
|
+
included_jobs = defined?(@all_jobs) ? @all_jobs : configuration.all_jobs
|
27
|
+
included_jobs.each_with_object([]) do |job_klass, acc|
|
28
|
+
acc << Worker::Instance.new(job_klass, configuration.enqueue_using_async)
|
77
29
|
end
|
78
30
|
end
|
79
|
-
raise errors if errors.size > 0
|
80
|
-
parsed_values
|
81
31
|
end
|
82
|
-
|
83
32
|
end
|
84
33
|
end
|
85
34
|
|
86
|
-
Sidekiq::Web
|
87
|
-
Sidekiq::Web.
|
88
|
-
Sidekiq::Web.
|
35
|
+
if defined?(Sidekiq::Web)
|
36
|
+
Sidekiq::Web.register Sidekiq::Enqueuer::WebExtension::Loader
|
37
|
+
Sidekiq::Web.tabs['Enqueuer'] = 'enqueuer'
|
38
|
+
Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), 'enqueuer/locales')
|
39
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Enqueuer
|
3
|
+
class Configuration
|
4
|
+
attr_accessor :jobs, :enqueue_using_async
|
5
|
+
|
6
|
+
IGNORED_CLASSES = %w(Sidekiq::Extensions
|
7
|
+
Sidekiq::Extensions::DelayedModel
|
8
|
+
Sidekiq::Extensions::DelayedMailer
|
9
|
+
Sidekiq::Extensions::DelayedClass
|
10
|
+
ActiveJob::QueueAdapters).freeze
|
11
|
+
|
12
|
+
def initialize(enqueue_using_async = nil)
|
13
|
+
@enqueue_using_async = true if enqueue_using_async.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
def all_jobs
|
17
|
+
@jobs = defined?(@jobs) ? sort(@jobs) : sort(application_jobs)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def sort(all_jobs)
|
23
|
+
all_jobs.sort_by(&:name)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Loads all jobs within the application after an eager_load
|
27
|
+
# Filters Sidekiq system Jobs
|
28
|
+
def application_jobs
|
29
|
+
rails_eager_load
|
30
|
+
all_jobs = []
|
31
|
+
all_jobs << sidekiq_jobs
|
32
|
+
all_jobs << active_jobs
|
33
|
+
all_jobs = all_jobs.flatten
|
34
|
+
all_jobs.delete_if { |klass| IGNORED_CLASSES.include?(klass.to_s) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def sidekiq_jobs
|
38
|
+
ObjectSpace.each_object(Class).select { |k| k.included_modules.include?(::Sidekiq::Worker) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def active_jobs
|
42
|
+
ObjectSpace.each_object(Class).select { |k| k.superclass == ::ActiveJob::Base }
|
43
|
+
end
|
44
|
+
|
45
|
+
# Load all classes from the included application before selecting Jobs from it
|
46
|
+
def rails_eager_load
|
47
|
+
::Rails.application.eager_load! if defined?(::Rails) && !::Rails.env.production?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,24 +1,26 @@
|
|
1
1
|
<h3>Enqueuer</h3>
|
2
2
|
|
3
3
|
<table class="table table-hover table-bordered table-striped table-white">
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
4
|
+
<thead>
|
5
|
+
<tr>
|
6
|
+
<th>Name</th>
|
7
|
+
<th>Params</th>
|
8
|
+
<th>Actions</th>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
<tbody>
|
12
|
+
<% @jobs.each do |job| %>
|
13
|
+
<tr>
|
14
|
+
<td width="40%"><%= job.name %></td>
|
15
|
+
<td width="40%"><%= job.params.map(&:name).join(', ') %></td>
|
16
|
+
<td width="20%">
|
17
|
+
<button class="btn btn-danger btn-xs">
|
18
|
+
<a href="<%= root_path %>enqueuer/<%= job.name %>" style="color: white;">
|
19
|
+
Enqueue Form
|
20
|
+
</a>
|
21
|
+
</button>
|
22
|
+
</td>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
</tbody>
|
26
|
+
</table>
|
@@ -1,63 +1,46 @@
|
|
1
1
|
<h3>Enqueuer</h3>
|
2
2
|
|
3
3
|
<div class="well">
|
4
|
-
|
5
|
-
|
4
|
+
<p>Support string value and hash value. Value will be stripped.</p>
|
5
|
+
<p>Start with { will be parsed by YAML as hash, eg: {k1: v1, k2: v2} to {'k1'=> 'v1', 'k2'=> 'v2'}. </p>
|
6
6
|
</div>
|
7
7
|
|
8
8
|
<form method="post" action="<%= root_path %>enqueuer">
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
</div>
|
47
|
-
<% end %>
|
48
|
-
|
49
|
-
<div class="form-group">
|
50
|
-
<input type="submit" class="btn btn-danger" name="submit" value="Enqueue" />
|
51
|
-
</div>
|
52
|
-
|
53
|
-
<div class="form-group">
|
54
|
-
<hr />
|
55
|
-
</div>
|
56
|
-
|
57
|
-
<div class="form-group">
|
58
|
-
<label for="enqueue_in">Enqueue in</label>
|
59
|
-
<input class="form-control" name="enqueue_in" placeholder="x seconds" />
|
60
|
-
</div>
|
61
|
-
|
62
|
-
<input type="submit" class="btn btn-danger" name="submit" value="Schedule" />
|
9
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
10
|
+
|
11
|
+
<div class="panel panel-default">
|
12
|
+
<div class="panel-heading">
|
13
|
+
<h3 class="panel-title">Perform</h3>
|
14
|
+
</div>
|
15
|
+
<div class="panel-body">
|
16
|
+
<div class="form-group">
|
17
|
+
<label for="job_class_name">Job Class/Module</label>
|
18
|
+
<input class="form-control" name="job_class_name" value="<%= @job.name %>" readonly=readonly />
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<% @job.params.each do |param| %>
|
22
|
+
<div class="form-group">
|
23
|
+
<label for="perform[<%= param %>]"><%= param.name %>
|
24
|
+
<span style="color: red; font-size: small;"> *<%= param.label %></span>
|
25
|
+
</label>
|
26
|
+
<input class="form-control" name="perform[<%= param.name %>]" />
|
27
|
+
</div>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<div class="form-group">
|
33
|
+
<input type="submit" class="btn btn-danger" name="submit" value="Enqueue" />
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div class="form-group">
|
37
|
+
<hr />
|
38
|
+
</div>
|
39
|
+
|
40
|
+
<div class="form-group">
|
41
|
+
<label for="enqueue_in">Enqueue in</label>
|
42
|
+
<input class="form-control" name="enqueue_in" placeholder="x seconds" />
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<input type="submit" class="btn btn-danger" name="submit" value="Schedule" />
|
63
46
|
</form>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Enqueuer
|
3
|
+
module WebExtension
|
4
|
+
module Helper
|
5
|
+
def get_params_by_action(name)
|
6
|
+
return [] if params[name].nil?
|
7
|
+
ParamsParser.new(params[name]).process
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_job_by_class_name(job_class_name)
|
11
|
+
Sidekiq::Enqueuer.all_jobs.find do |job_klass|
|
12
|
+
job_klass.job == job_class_name || job_klass.job.to_s == job_class_name || job_klass.name == job_class_name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# TODO: Figure out the need of unlock!
|
17
|
+
# def does_job_have_unlock_method(klass_or_module)
|
18
|
+
# klass_or_module.respond_to?(:unlock!)
|
19
|
+
# false
|
20
|
+
# end
|
21
|
+
|
22
|
+
# TODO: Figure out the need of unlock!
|
23
|
+
# def get_job_unlock_params(klass_or_module)
|
24
|
+
# klass_or_module.method(:unlock!).parameters.map{ |e| e[1]}
|
25
|
+
# end
|
26
|
+
|
27
|
+
# TODO: Figure out the need of unlock!
|
28
|
+
# def self.unlock!(klass, values)
|
29
|
+
# parsed_values = values_parser(values)
|
30
|
+
# klass.unlock!(*parsed_values)
|
31
|
+
# end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Enqueuer
|
3
|
+
module WebExtension
|
4
|
+
module Loader
|
5
|
+
def self.registered(app)
|
6
|
+
view_path = File.join(File.expand_path('../..', __FILE__), 'views')
|
7
|
+
app.helpers WebExtension::Helper
|
8
|
+
|
9
|
+
app.get '/enqueuer' do
|
10
|
+
@jobs = Sidekiq::Enqueuer.all_jobs
|
11
|
+
render(:erb, File.read(File.join(view_path, 'index.erb')))
|
12
|
+
end
|
13
|
+
|
14
|
+
app.get '/enqueuer/:job_class_name' do
|
15
|
+
@job = find_job_by_class_name(params[:job_class_name])
|
16
|
+
render(:erb, File.read(File.join(view_path, 'new.erb')))
|
17
|
+
end
|
18
|
+
|
19
|
+
app.post '/enqueuer' do
|
20
|
+
job = find_job_by_class_name(params[:job_class_name])
|
21
|
+
requested_params = get_params_by_action('perform')
|
22
|
+
# TODO: Figure out the need of unlock!
|
23
|
+
# if params['unlock-enable'] && params['unlock-enable'] != ''
|
24
|
+
# Sidekiq::Enqueuer.unlock!(klass, get_params_by_action('unlock'))
|
25
|
+
# end
|
26
|
+
if job
|
27
|
+
job.trigger(requested_params) if params['submit'] == 'Enqueue'
|
28
|
+
job.trigger_in(params['enqueue_in'], requested_params) if params['submit'] == 'Schedule'
|
29
|
+
end
|
30
|
+
redirect "#{root_path}enqueuer"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Enqueuer
|
3
|
+
module WebExtension
|
4
|
+
class ParamsParser
|
5
|
+
attr_reader :raw_params
|
6
|
+
|
7
|
+
def initialize(params)
|
8
|
+
@raw_params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
def process
|
12
|
+
all_params = filter_empty(raw_params)
|
13
|
+
hash_params = yaml_to_params(all_params.values)
|
14
|
+
all_params = hash_params.merge!(all_params) if hash_params
|
15
|
+
simple_params = filter_complex(all_params)
|
16
|
+
simple_params.values.compact.flatten
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def yaml_to_params(values)
|
22
|
+
unique_params = {}
|
23
|
+
values.each do |str_param|
|
24
|
+
param_hash = expected_hash?(str_param) ? convert_to_ruby(str_param) : {}
|
25
|
+
unique_params.merge!(param_hash)
|
26
|
+
end
|
27
|
+
unique_params
|
28
|
+
end
|
29
|
+
|
30
|
+
def filter_empty(given_params)
|
31
|
+
given_params.delete_if { |_, v| v.to_s.empty? }
|
32
|
+
end
|
33
|
+
|
34
|
+
def filter_complex(given_params)
|
35
|
+
given_params.delete_if { |_, v| expected_hash?(v.to_s) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def convert_to_ruby(value)
|
39
|
+
YAML.parse(value.to_s.strip).to_ruby
|
40
|
+
end
|
41
|
+
|
42
|
+
def expected_hash?(value)
|
43
|
+
value.to_s.start_with?('{') && value.to_s.end_with?('}')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Enqueuer
|
3
|
+
module Worker
|
4
|
+
class Instance
|
5
|
+
attr_reader :job, :instance_method, :params, :enqueue_using_async
|
6
|
+
|
7
|
+
def initialize(job, enqueue_using_async)
|
8
|
+
@job = job
|
9
|
+
@enqueue_using_async = enqueue_using_async
|
10
|
+
@instance_method = deduce_instance_method
|
11
|
+
@params = deduce_params
|
12
|
+
end
|
13
|
+
|
14
|
+
def trigger(input_params)
|
15
|
+
trigger_job(input_params).enqueue
|
16
|
+
end
|
17
|
+
|
18
|
+
def trigger_in(seconds, input_params)
|
19
|
+
trigger_job(input_params).enqueue_in(seconds.to_s.to_i.seconds)
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@job.name
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def trigger_job(input_params)
|
29
|
+
Trigger.new(job, input_params)
|
30
|
+
end
|
31
|
+
|
32
|
+
# TODO: what if two of this methods exist? which one to pick to figure out params?
|
33
|
+
def deduce_instance_method
|
34
|
+
[:perform, :perform_in, :perform_async, :perform_at].each do |evaluating_method|
|
35
|
+
return evaluating_method if job.instance_methods.include?(evaluating_method)
|
36
|
+
end
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def deduce_params
|
41
|
+
worker_params.empty? ? [] : worker_params.map { |e| Param.new(e[1], e[0]) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def worker_params
|
45
|
+
job.instance_method(instance_method).parameters
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Enqueuer
|
3
|
+
module Worker
|
4
|
+
class Param
|
5
|
+
attr_reader :name, :condition
|
6
|
+
|
7
|
+
VALID_OPTIONS = { req: 'required', opt: 'optional' }.freeze
|
8
|
+
|
9
|
+
def initialize(name, condition)
|
10
|
+
@name = name
|
11
|
+
@condition = VALID_OPTIONS[condition]
|
12
|
+
end
|
13
|
+
|
14
|
+
def label
|
15
|
+
condition
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Enqueuer
|
3
|
+
module Worker
|
4
|
+
class Trigger
|
5
|
+
class UnsupportedJobType < StandardError; end
|
6
|
+
|
7
|
+
attr_reader :job, :queue, :args_with_values
|
8
|
+
|
9
|
+
def initialize(job, input_param_hash)
|
10
|
+
@job = job
|
11
|
+
@queue = deduce_queue
|
12
|
+
@args_with_values = input_param_hash
|
13
|
+
end
|
14
|
+
|
15
|
+
def enqueue
|
16
|
+
if sidekiq_job?
|
17
|
+
Sidekiq::Client.enqueue_to(queue, job, *args_with_values)
|
18
|
+
elsif active_job?
|
19
|
+
return job.perform_later(*args_with_values)
|
20
|
+
else
|
21
|
+
raise UnsupportedJobType
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def enqueue_in(time_in_seconds)
|
26
|
+
if sidekiq_job?
|
27
|
+
Sidekiq::Client.enqueue_to_in(queue, time_in_seconds, job, *args_with_values)
|
28
|
+
elsif active_job?
|
29
|
+
job.set(wait: time_in_seconds).perform_later(*args_with_values)
|
30
|
+
else
|
31
|
+
raise UnsupportedJobType
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def deduce_queue
|
38
|
+
job.respond_to?(:sidekiq_options) ? job.sidekiq_options['queue'].to_s : 'default'
|
39
|
+
end
|
40
|
+
|
41
|
+
def sidekiq_job?
|
42
|
+
job.included_modules.include? ::Sidekiq::Worker
|
43
|
+
end
|
44
|
+
|
45
|
+
def active_job?
|
46
|
+
job.superclass == ::ActiveJob::Base
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/sidekiq-enqueuer.gemspec
CHANGED
@@ -4,14 +4,14 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'sidekiq/enqueuer/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'sidekiq-enqueuer'
|
8
8
|
spec.version = Sidekiq::Enqueuer::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['richfisher']
|
10
|
+
spec.email = ['richfisher.pan@gmail.com']
|
11
11
|
|
12
12
|
spec.summary = %q{A Sidekiq Web extension to enqueue/schedule jobs with custom perform params in Web UI.}
|
13
13
|
spec.description = %q{A Sidekiq Web extension to enqueue/schedule jobs with custom perform params in Web UI. Support both Sidekiq::Worker and ActiveJob.}
|
14
|
-
spec.homepage =
|
14
|
+
spec.homepage = 'https://github.com/richfisher/sidekiq-enqueuer'
|
15
15
|
|
16
16
|
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
17
17
|
# delete this section to allow pushing this gem to any host.
|
@@ -22,14 +22,14 @@ Gem::Specification.new do |spec|
|
|
22
22
|
# end
|
23
23
|
|
24
24
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
-
spec.bindir =
|
25
|
+
spec.bindir = 'exe'
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
-
spec.require_paths = [
|
27
|
+
spec.require_paths = ['lib']
|
28
28
|
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
29
|
+
spec.add_development_dependency 'bundler'
|
30
|
+
spec.add_development_dependency 'rake'
|
31
|
+
spec.add_development_dependency 'rack-test'
|
32
|
+
spec.add_development_dependency 'sidekiq'
|
33
|
+
spec.add_development_dependency 'rails', '> 4.2'
|
34
|
+
spec.add_development_dependency 'sinatra'
|
35
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-enqueuer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- richfisher
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -105,7 +105,7 @@ files:
|
|
105
105
|
- ".gitignore"
|
106
106
|
- ".ruby-version"
|
107
107
|
- ".travis.yml"
|
108
|
-
-
|
108
|
+
- CHANGELOG.md
|
109
109
|
- Gemfile
|
110
110
|
- README.md
|
111
111
|
- Rakefile
|
@@ -113,12 +113,18 @@ files:
|
|
113
113
|
- bin/setup
|
114
114
|
- lib/sidekiq-enqueuer.rb
|
115
115
|
- lib/sidekiq/enqueuer.rb
|
116
|
+
- lib/sidekiq/enqueuer/configuration.rb
|
116
117
|
- lib/sidekiq/enqueuer/locales/en.yml
|
117
118
|
- lib/sidekiq/enqueuer/railtie.rb
|
118
119
|
- lib/sidekiq/enqueuer/version.rb
|
119
120
|
- lib/sidekiq/enqueuer/views/index.erb
|
120
121
|
- lib/sidekiq/enqueuer/views/new.erb
|
121
|
-
- lib/sidekiq/enqueuer/web_extension.rb
|
122
|
+
- lib/sidekiq/enqueuer/web_extension/helper.rb
|
123
|
+
- lib/sidekiq/enqueuer/web_extension/loader.rb
|
124
|
+
- lib/sidekiq/enqueuer/web_extension/params_parser.rb
|
125
|
+
- lib/sidekiq/enqueuer/worker/instance.rb
|
126
|
+
- lib/sidekiq/enqueuer/worker/param.rb
|
127
|
+
- lib/sidekiq/enqueuer/worker/trigger.rb
|
122
128
|
- sidekiq-enqueuer.gemspec
|
123
129
|
homepage: https://github.com/richfisher/sidekiq-enqueuer
|
124
130
|
licenses: []
|
@@ -134,9 +140,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
134
140
|
version: '0'
|
135
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
142
|
requirements:
|
137
|
-
- - "
|
143
|
+
- - ">"
|
138
144
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
145
|
+
version: 1.3.1
|
140
146
|
requirements: []
|
141
147
|
rubyforge_project:
|
142
148
|
rubygems_version: 2.4.8
|
data/Changes.md
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
module Sidekiq::Enqueuer::WebExtension
|
2
|
-
def self.registered(app)
|
3
|
-
view_path = File.join(File.expand_path("..", __FILE__), "views")
|
4
|
-
|
5
|
-
app.helpers do
|
6
|
-
def get_job_perform_params(klass_or_module)
|
7
|
-
klass_or_module.instance_method(:perform).parameters.map{ |e| e[1]}
|
8
|
-
end
|
9
|
-
|
10
|
-
def does_job_have_unlock_method(klass_or_module)
|
11
|
-
klass_or_module.respond_to?(:unlock!)
|
12
|
-
end
|
13
|
-
|
14
|
-
def get_job_unlock_params(klass_or_module)
|
15
|
-
klass_or_module.method(:unlock!).parameters.map{ |e| e[1]}
|
16
|
-
end
|
17
|
-
|
18
|
-
def get_params_by_name(name)
|
19
|
-
params[name].nil? ? [] : params[name].values
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
app.get "/enqueuer" do
|
24
|
-
@jobs = Sidekiq::Enqueuer.get_jobs
|
25
|
-
|
26
|
-
render(:erb, File.read(File.join(view_path, "index.erb")))
|
27
|
-
end
|
28
|
-
|
29
|
-
app.get "/enqueuer/:job_class_name" do
|
30
|
-
@klass = params[:job_class_name].constantize
|
31
|
-
render(:erb, File.read(File.join(view_path, "new.erb")))
|
32
|
-
end
|
33
|
-
|
34
|
-
app.post "/enqueuer" do
|
35
|
-
klass = params[:job_class_name].constantize
|
36
|
-
|
37
|
-
if params['unlock-enable'] && params['unlock-enable'] != ''
|
38
|
-
Sidekiq::Enqueuer.unlock!(klass, get_params_by_name('unlock'))
|
39
|
-
end
|
40
|
-
|
41
|
-
if params['submit'] == 'Enqueue'
|
42
|
-
Sidekiq::Enqueuer.perform_async(klass, get_params_by_name('perform'))
|
43
|
-
end
|
44
|
-
|
45
|
-
if params['submit'] == 'Schedule'
|
46
|
-
Sidekiq::Enqueuer.perform_in(klass, params['enqueue_in'], get_params_by_name('perform'))
|
47
|
-
end
|
48
|
-
|
49
|
-
redirect "#{root_path}enqueuer"
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|