sidekiq_adhoc_job 0.1.6 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b485f48179615a49f00e4a39c0ff9b7d4ffe77ef9336e331d875633c1ccdf82
4
- data.tar.gz: c0f7d9316a7cff046ebe6ef03fea42206ff0c195c5e6081fe80750e5de5f98c9
3
+ metadata.gz: c21a2663558c918e59402c9180737fdc70f7520003413770eecaa73cabf86db8
4
+ data.tar.gz: f0eb1fd9b4c6e9d7b7fd52eaa157bd468bc02585438413c27b42a933097b5ca9
5
5
  SHA512:
6
- metadata.gz: 427a776633fa687204e6a7d73f7ef95c0e3fc3a77995fccbb4ab84a78bd3a51c731f98ee7ffa3886df6f9e98bd735dd5a73136c2bf5f45e028d3de1a0c60edbe
7
- data.tar.gz: c4897277ab341b525cd4dcf1b4943cac66ba27a46d581d91334f32eb8867c0bf300d96eb342093c10530a43d4cb0f1e85cb08b1dad852e0f746e20d1ffd6b8bd
6
+ metadata.gz: cc04bca685843cdc4f68758fbef688bfaaca75ab64deaaece3cb3e082dd54c028230753e1c8d7d2b8001089584c8b6a4fb578fbb2582f22fd604c0a30b492bb9
7
+ data.tar.gz: 5c3bb8282be7d70ff5a5937b41e7be4db4d4ab4568b302030aef2da554ede3a89e8d9b45afafbd5820b4bc68fc22b75bebb7ffbce183c9c8c773878c5bbb8fa0
@@ -3,6 +3,7 @@ require 'sidekiq/web'
3
3
 
4
4
  require 'sidekiq_adhoc_job/utils/string'
5
5
  require 'sidekiq_adhoc_job/utils/class_inspector'
6
+ require 'sidekiq_adhoc_job/strategy'
6
7
  require 'sidekiq_adhoc_job/worker_classes_loader'
7
8
  require 'sidekiq_adhoc_job/web/job_presenter'
8
9
  require 'sidekiq_adhoc_job/services/schedule_adhoc_job'
@@ -10,6 +11,13 @@ require 'sidekiq_adhoc_job/web'
10
11
 
11
12
  module SidekiqAdhocJob
12
13
 
14
+ StringUtil ||= Utils::String
15
+
16
+ module Strategies
17
+ autoload :Default, 'sidekiq_adhoc_job/strategies/default'
18
+ autoload :ActiveJob, 'sidekiq_adhoc_job/strategies/active_job'
19
+ end
20
+
13
21
  def self.configure
14
22
  @_config = Configuration.new
15
23
  yield @_config
@@ -20,23 +28,40 @@ module SidekiqAdhocJob
20
28
  end
21
29
 
22
30
  def self.init
23
- SidekiqAdhocJob::WorkerClassesLoader.load(@_config.module_names)
31
+ SidekiqAdhocJob::WorkerClassesLoader.load(@_config.module_names, load_paths: @_config.load_paths, strategy: @_config.strategy)
24
32
 
25
33
  Sidekiq::Web.register(SidekiqAdhocJob::Web)
26
34
  Sidekiq::Web.tabs['adhoc_jobs'] = 'adhoc-jobs'
27
35
  Sidekiq::Web.locales << File.expand_path('sidekiq_adhoc_job/web/locales', __dir__)
28
36
  end
29
37
 
38
+ def self.strategies
39
+ @_strategies ||= []
40
+ end
41
+
30
42
  class Configuration
31
- attr_accessor :module_names
43
+ attr_accessor :load_paths, :module_names, :strategy_name
32
44
 
33
45
  def initialize
46
+ @load_paths = []
34
47
  @module_names = []
48
+ @strategy_name = :default
35
49
  end
36
50
 
37
51
  def module_names
38
52
  Array(@module_names).map(&:to_s)
39
53
  end
54
+
55
+ def strategy
56
+ @strategy ||= case strategy_name
57
+ when :default
58
+ SidekiqAdhocJob::Strategies::Default.new(module_names)
59
+ else
60
+ strategy_klass = SidekiqAdhocJob::Strategies.const_get(StringUtil.camelize(strategy_name.to_s).to_s)
61
+ raise InvalidConfigurationError, "Invalid strategy name" unless strategy_klass
62
+ strategy_klass.new(module_names)
63
+ end
64
+ end
40
65
  end
41
66
 
42
67
  end
@@ -16,7 +16,7 @@ module SidekiqAdhocJob
16
16
  end
17
17
 
18
18
  def call
19
- worker_klass.perform_async(*worker_params)
19
+ SidekiqAdhocJob.config.strategy.perform_async(worker_klass, *worker_params)
20
20
  end
21
21
 
22
22
  private
@@ -25,9 +25,9 @@ module SidekiqAdhocJob
25
25
  :allowed_params, :worker_params
26
26
 
27
27
  def parse_params
28
- @worker_params = allowed_params.map { |key| StringUtil.parse(request_params[key]) }
28
+ @worker_params = allowed_params.map { |key| StringUtil.parse(request_params[key], symbolize: true) }
29
29
  if !!request_params[:rest_args] && !request_params[:rest_args].empty?
30
- @worker_params += request_params[:rest_args].split(',').map { |arg| StringUtil.parse(arg.strip) }
30
+ @worker_params << StringUtil.parse_json(request_params[:rest_args].strip, symbolize: true)
31
31
  end
32
32
  end
33
33
 
@@ -0,0 +1,19 @@
1
+ module SidekiqAdhocJob
2
+ module Strategies
3
+ class ActiveJob
4
+ include SidekiqAdhocJob::Strategy
5
+
6
+ def worker_class?(klass)
7
+ klass.superclass&.name == 'ActiveJob::Base'
8
+ end
9
+
10
+ def get_queue_name(klass_name)
11
+ klass_name.queue_name
12
+ end
13
+
14
+ def perform_async(klass, *params)
15
+ klass.perform_later(*params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SidekiqAdhocJob
2
+ module Strategies
3
+ class Default
4
+ include SidekiqAdhocJob::Strategy
5
+
6
+ def worker_class?(klass)
7
+ klass.included_modules.include?(Sidekiq::Worker)
8
+ end
9
+
10
+ def get_queue_name(klass_name)
11
+ klass_name.sidekiq_options['queue']
12
+ end
13
+
14
+ def perform_async(klass, *params)
15
+ klass.perform_async(*params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,43 @@
1
+ module SidekiqAdhocJob
2
+ module Strategy
3
+ def self.included(base)
4
+ SidekiqAdhocJob.strategies << base
5
+
6
+ base.extend ClassMethods
7
+ base.class_eval do
8
+ end
9
+ end
10
+
11
+ attr_reader :module_names, :worker_klasses
12
+
13
+ StringUtil ||= SidekiqAdhocJob::Utils::String
14
+
15
+ def initialize(module_names)
16
+ @module_names = module_names
17
+ @worker_klasses = {}
18
+ end
19
+
20
+ def load
21
+ ObjectSpace.each_object(Class).each do |klass|
22
+ next unless klass
23
+
24
+ if worker_class?(klass) && allowed_namespace?(klass.name, allowlist: module_names)
25
+ @worker_klasses[worker_path_name(klass.name)] = klass
26
+ end
27
+ end
28
+ end
29
+
30
+ def allowed_namespace?(class_name, allowlist:)
31
+ return true if allowlist.empty? || allowlist.include?('Module') # allow any namespace
32
+
33
+ allowlist.any? { |prefix| class_name.start_with?(prefix) }
34
+ end
35
+
36
+ def worker_path_name(worker_name)
37
+ Utils::String.underscore(worker_name).gsub('/', '_')
38
+ end
39
+
40
+ module ClassMethods
41
+ end
42
+ end
43
+ end
@@ -1,4 +1,5 @@
1
1
  # References: https://github.com/hanami/utils/blob/master/lib/hanami/utils/string.rb
2
+ # https://github.com/omniauth/omniauth/blob/cc0f5522621b4a372f4dff0aa608822aa082cb60/lib/omniauth.rb#L156
2
3
  module SidekiqAdhocJob
3
4
  module Utils
4
5
  class String
@@ -75,7 +76,15 @@ module SidekiqAdhocJob
75
76
  constant
76
77
  end
77
78
 
78
- def self.parse(input)
79
+ def self.camelize(word, first_letter_in_uppercase = true)
80
+ if first_letter_in_uppercase
81
+ word.to_s.gsub(%r{/(.?)}) { '::' + Regexp.last_match[1].upcase }.gsub(/(^|_)(.)/) { Regexp.last_match[2].upcase }
82
+ else
83
+ word.first + self.camelize(word)[1..-1]
84
+ end
85
+ end
86
+
87
+ def self.parse(input, symbolize: false)
79
88
  return unless input
80
89
 
81
90
  if input == 'true'
@@ -88,7 +97,7 @@ module SidekiqAdhocJob
88
97
  i
89
98
  elsif (f = parse_float(input))
90
99
  f
91
- elsif (j = parse_json(input))
100
+ elsif (j = parse_json(input, symbolize: symbolize))
92
101
  j
93
102
  else
94
103
  input
@@ -107,8 +116,8 @@ module SidekiqAdhocJob
107
116
  nil
108
117
  end
109
118
 
110
- def self.parse_json(input)
111
- JSON.parse(input)
119
+ def self.parse_json(input, symbolize: false)
120
+ JSON.parse(input, symbolize_names: symbolize)
112
121
  rescue JSON::ParserError => _e
113
122
  nil
114
123
  end
@@ -1,3 +1,3 @@
1
1
  module SidekiqAdhocJob
2
- VERSION = '0.1.6'.freeze
2
+ VERSION = '0.2.1'.freeze
3
3
  end
@@ -38,7 +38,7 @@ module SidekiqAdhocJob
38
38
  end
39
39
 
40
40
  def self.convert_klass_name_to_presenter(path_name, klass_name)
41
- queue = klass_name.sidekiq_options['queue']
41
+ queue = SidekiqAdhocJob.config.strategy.get_queue_name(klass_name)
42
42
  class_inspector = SidekiqAdhocJob::Utils::ClassInspector.new(klass_name)
43
43
  args = class_inspector.parameters(:perform)
44
44
  new(klass_name, path_name, queue, args)
@@ -1,5 +1,7 @@
1
1
  <h3><%= t('adhoc_jobs') %></h3>
2
2
 
3
+ <h4><%= SidekiqAdhocJob::Utils::String.classify(@presented_job.path_name) %></h4>
4
+
3
5
  <form method="POST" action="<%= root_path %>adhoc-jobs/<%= URI.escape(@presented_job.path_name) %>/schedule">
4
6
  <input type="hidden" name="authenticity_token" value="<%= @csrf_token %>" />
5
7
  <% if @presented_job.args.empty? && !@presented_job.has_rest_args %>
@@ -15,7 +17,7 @@
15
17
  <% end %>
16
18
  <% if @presented_job.has_rest_args %>
17
19
  <div class="form-group row">
18
- <label class="col-sm-2 col-form-label" for="rest_args">*Rest arguments (please separate each argument by comma):</label>
20
+ <label class="col-sm-2 col-form-label" for="rest_args">*Rest arguments (please provide a json string representing the arguments):</label>
19
21
  <div class="col-sm-4">
20
22
  <input class="form-control" type="text" name="rest_args" id="rest_args" required/>
21
23
  </div>
@@ -2,12 +2,10 @@ module SidekiqAdhocJob
2
2
  class WorkerClassesLoader
3
3
  @_worker_klasses = {}
4
4
 
5
- def self.load(module_names)
6
- ObjectSpace.each_object(Class).each do |klass|
7
- if worker_class?(klass) && allowed_namespace?(klass.name, allowlist: module_names)
8
- @_worker_klasses[worker_path_name(klass.name)] = klass
9
- end
10
- end
5
+ def self.load(module_names, strategy:, load_paths:)
6
+ require_files(load_paths)
7
+ strategy.load
8
+ @_worker_klasses = strategy.worker_klasses
11
9
  end
12
10
 
13
11
  def self.worker_klasses
@@ -18,21 +16,8 @@ module SidekiqAdhocJob
18
16
  @_worker_klasses[path_name]
19
17
  end
20
18
 
21
- def self.worker_class?(klass)
22
- klass.included_modules.include?(Sidekiq::Worker)
19
+ def self.require_files(load_paths)
20
+ Dir[File.join("", load_paths)].each { |path| require path } unless load_paths.empty?
23
21
  end
24
- private_class_method :worker_class?
25
-
26
- def self.allowed_namespace?(class_name, allowlist:)
27
- return true if allowlist.empty? || allowlist.include?('Module') # allow any namespace
28
-
29
- allowlist.any? { |prefix| class_name.start_with?(prefix) }
30
- end
31
- private_class_method :allowed_namespace?
32
-
33
- def self.worker_path_name(worker_name)
34
- Utils::String.underscore(worker_name).gsub('/', '_')
35
- end
36
- private_class_method :worker_path_name
37
22
  end
38
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq_adhoc_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Goh Khoon Hiang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-04 00:00:00.000000000 Z
11
+ date: 2020-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -98,14 +98,14 @@ dependencies:
98
98
  name: sidekiq
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: 5.2.7
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: 5.2.7
111
111
  description: Trigger jobs adhoc from Sidekiq web admin
@@ -117,6 +117,9 @@ extra_rdoc_files: []
117
117
  files:
118
118
  - lib/sidekiq_adhoc_job.rb
119
119
  - lib/sidekiq_adhoc_job/services/schedule_adhoc_job.rb
120
+ - lib/sidekiq_adhoc_job/strategies/active_job.rb
121
+ - lib/sidekiq_adhoc_job/strategies/default.rb
122
+ - lib/sidekiq_adhoc_job/strategy.rb
120
123
  - lib/sidekiq_adhoc_job/utils/class_inspector.rb
121
124
  - lib/sidekiq_adhoc_job/utils/string.rb
122
125
  - lib/sidekiq_adhoc_job/version.rb