rocketjob 5.1.1 → 5.2.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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rocketjob +2 -2
  3. data/bin/rocketjob_batch_perf +1 -1
  4. data/bin/rocketjob_perf +1 -1
  5. data/lib/rocket_job/active_worker.rb +1 -0
  6. data/lib/rocket_job/batch.rb +16 -17
  7. data/lib/rocket_job/batch/callbacks.rb +1 -2
  8. data/lib/rocket_job/batch/io.rb +10 -6
  9. data/lib/rocket_job/batch/logger.rb +2 -2
  10. data/lib/rocket_job/batch/lower_priority.rb +2 -2
  11. data/lib/rocket_job/batch/model.rb +23 -23
  12. data/lib/rocket_job/batch/performance.rb +19 -21
  13. data/lib/rocket_job/batch/result.rb +1 -1
  14. data/lib/rocket_job/batch/results.rb +1 -1
  15. data/lib/rocket_job/batch/state_machine.rb +5 -6
  16. data/lib/rocket_job/batch/statistics.rb +10 -8
  17. data/lib/rocket_job/batch/tabular.rb +2 -2
  18. data/lib/rocket_job/batch/tabular/input.rb +11 -7
  19. data/lib/rocket_job/batch/tabular/output.rb +1 -1
  20. data/lib/rocket_job/batch/throttle.rb +11 -30
  21. data/lib/rocket_job/batch/{throttle_running_slices.rb → throttle_running_workers.rb} +13 -10
  22. data/lib/rocket_job/batch/worker.rb +102 -85
  23. data/lib/rocket_job/cli.rb +57 -54
  24. data/lib/rocket_job/config.rb +8 -10
  25. data/lib/rocket_job/dirmon_entry.rb +13 -10
  26. data/lib/rocket_job/event.rb +16 -16
  27. data/lib/rocket_job/extensions/mongo/logging.rb +2 -2
  28. data/lib/rocket_job/extensions/mongoid/clients/options.rb +2 -2
  29. data/lib/rocket_job/extensions/mongoid/contextual/mongo.rb +4 -2
  30. data/lib/rocket_job/extensions/mongoid/factory.rb +13 -5
  31. data/lib/rocket_job/extensions/rocket_job_adapter.rb +2 -1
  32. data/lib/rocket_job/job_exception.rb +0 -3
  33. data/lib/rocket_job/jobs/dirmon_job.rb +4 -4
  34. data/lib/rocket_job/jobs/housekeeping_job.rb +7 -7
  35. data/lib/rocket_job/jobs/on_demand_batch_job.rb +14 -4
  36. data/lib/rocket_job/jobs/on_demand_job.rb +3 -3
  37. data/lib/rocket_job/jobs/performance_job.rb +1 -1
  38. data/lib/rocket_job/jobs/re_encrypt/relational_job.rb +11 -10
  39. data/lib/rocket_job/jobs/upload_file_job.rb +9 -5
  40. data/lib/rocket_job/performance.rb +24 -22
  41. data/lib/rocket_job/plugins/cron.rb +7 -3
  42. data/lib/rocket_job/plugins/document.rb +7 -5
  43. data/lib/rocket_job/plugins/job/callbacks.rb +1 -1
  44. data/lib/rocket_job/plugins/job/logger.rb +3 -3
  45. data/lib/rocket_job/plugins/job/model.rb +34 -27
  46. data/lib/rocket_job/plugins/job/persistence.rb +7 -34
  47. data/lib/rocket_job/plugins/job/state_machine.rb +5 -4
  48. data/lib/rocket_job/plugins/job/throttle.rb +12 -28
  49. data/lib/rocket_job/plugins/job/throttle_running_jobs.rb +2 -2
  50. data/lib/rocket_job/plugins/job/worker.rb +22 -70
  51. data/lib/rocket_job/plugins/processing_window.rb +5 -4
  52. data/lib/rocket_job/plugins/restart.rb +3 -3
  53. data/lib/rocket_job/plugins/retry.rb +2 -2
  54. data/lib/rocket_job/plugins/singleton.rb +1 -2
  55. data/lib/rocket_job/plugins/state_machine.rb +4 -4
  56. data/lib/rocket_job/plugins/transaction.rb +1 -1
  57. data/lib/rocket_job/rocket_job.rb +5 -4
  58. data/lib/rocket_job/server.rb +2 -2
  59. data/lib/rocket_job/server/model.rb +14 -13
  60. data/lib/rocket_job/server/state_machine.rb +1 -2
  61. data/lib/rocket_job/sliced/compressed_slice.rb +4 -4
  62. data/lib/rocket_job/sliced/encrypted_slice.rb +4 -4
  63. data/lib/rocket_job/sliced/input.rb +16 -16
  64. data/lib/rocket_job/sliced/output.rb +2 -2
  65. data/lib/rocket_job/sliced/slice.rb +43 -20
  66. data/lib/rocket_job/sliced/slices.rb +14 -11
  67. data/lib/rocket_job/subscriber.rb +6 -6
  68. data/lib/rocket_job/subscribers/logger.rb +3 -3
  69. data/lib/rocket_job/supervisor.rb +12 -12
  70. data/lib/rocket_job/supervisor/shutdown.rb +7 -7
  71. data/lib/rocket_job/throttle_definition.rb +37 -0
  72. data/lib/rocket_job/throttle_definitions.rb +39 -0
  73. data/lib/rocket_job/version.rb +1 -1
  74. data/lib/rocket_job/worker.rb +116 -34
  75. data/lib/rocket_job/worker_pool.rb +6 -6
  76. data/lib/rocketjob.rb +72 -76
  77. metadata +16 -18
  78. data/lib/rocket_job/extensions/mongoid_5/clients/options.rb +0 -38
  79. data/lib/rocket_job/extensions/mongoid_5/contextual/mongo.rb +0 -64
  80. data/lib/rocket_job/extensions/mongoid_5/factory.rb +0 -13
@@ -1,9 +1,9 @@
1
- require 'optparse'
2
- require 'json'
3
- require 'semantic_logger'
4
- require 'mongoid'
5
- require 'rocketjob'
6
- require 'pathname'
1
+ require "optparse"
2
+ require "json"
3
+ require "semantic_logger"
4
+ require "mongoid"
5
+ require "rocketjob"
6
+ require "pathname"
7
7
  module RocketJob
8
8
  # Command Line Interface parser for Rocket Job
9
9
  class CLI
@@ -18,7 +18,7 @@ module RocketJob
18
18
  @quiet = false
19
19
  @environment = nil
20
20
  @pidfile = nil
21
- @directory = '.'
21
+ @directory = "."
22
22
  @log_level = nil
23
23
  @log_file = nil
24
24
  @mongo_config = nil
@@ -36,7 +36,7 @@ module RocketJob
36
36
 
37
37
  # Run a RocketJob::Server from the command line
38
38
  def run
39
- Thread.current.name = 'rocketjob main'
39
+ Thread.current.name = "rocketjob main"
40
40
  RocketJob.server! if server
41
41
  setup_environment
42
42
  setup_logger
@@ -60,7 +60,7 @@ module RocketJob
60
60
  def rails?
61
61
  @rails ||=
62
62
  begin
63
- boot_file = Pathname.new(directory).join('config/environment.rb').expand_path
63
+ boot_file = Pathname.new(directory).join("config/environment.rb").expand_path
64
64
  boot_file.file?
65
65
  end
66
66
  end
@@ -71,13 +71,13 @@ module RocketJob
71
71
  logger.info "Loading Rails environment: #{environment}"
72
72
  RocketJob.rails!
73
73
 
74
- require 'rails'
75
- require 'rocket_job/railtie'
76
- boot_file = Pathname.new(directory).join('config/environment.rb').expand_path
74
+ require "rails"
75
+ require "rocket_job/railtie"
76
+ boot_file = Pathname.new(directory).join("config/environment.rb").expand_path
77
77
  require(boot_file.to_s)
78
78
 
79
79
  begin
80
- require 'rails_semantic_logger'
80
+ require "rails_semantic_logger"
81
81
  rescue LoadError
82
82
  raise "Add the following line to your Gemfile when running rails:\n gem 'rails_semantic_logger'"
83
83
  end
@@ -87,10 +87,10 @@ module RocketJob
87
87
 
88
88
  return unless Rails.configuration.eager_load
89
89
 
90
- logger.measure_info('Eager loaded Rails and all Engines') do
90
+ logger.measure_info("Eager loaded Rails and all Engines") do
91
91
  Rails.application.eager_load!
92
92
  Rails::Engine.subclasses.each(&:eager_load!)
93
- self.class.eager_load_jobs(File.expand_path('jobs', File.dirname(__FILE__)))
93
+ self.class.eager_load_jobs(File.expand_path("jobs", File.dirname(__FILE__)))
94
94
  end
95
95
  end
96
96
 
@@ -98,13 +98,13 @@ module RocketJob
98
98
  def boot_standalone
99
99
  # Try to load bundler if present
100
100
  begin
101
- require 'bundler/setup'
101
+ require "bundler/setup"
102
102
  Bundler.require(environment)
103
103
  rescue LoadError
104
104
  nil
105
105
  end
106
106
 
107
- require 'rocketjob'
107
+ require "rocketjob"
108
108
 
109
109
  # Log to file except when booting rails, when it will add the log file path
110
110
  path = log_file ? Pathname.new(log_file) : Pathname.pwd.join("log/#{environment}.log")
@@ -113,7 +113,7 @@ module RocketJob
113
113
 
114
114
  logger.info "Rails not detected. Running standalone: #{environment}"
115
115
  RocketJob::Config.load!(environment, mongo_config, symmetric_encryption_config)
116
- self.class.eager_load_jobs(File.expand_path('jobs', File.dirname(__FILE__)))
116
+ self.class.eager_load_jobs(File.expand_path("jobs", File.dirname(__FILE__)))
117
117
  self.class.eager_load_jobs
118
118
  end
119
119
 
@@ -128,8 +128,9 @@ module RocketJob
128
128
  # Create a PID file if requested
129
129
  def write_pidfile
130
130
  return unless pidfile
131
+
131
132
  pid = $PID
132
- File.open(pidfile, 'w') { |f| f.puts(pid) }
133
+ File.open(pidfile, "w") { |f| f.puts(pid) }
133
134
 
134
135
  # Remove pidfile on exit
135
136
  at_exit do
@@ -140,9 +141,9 @@ module RocketJob
140
141
  def setup_environment
141
142
  # Override Env vars when environment is supplied
142
143
  if environment
143
- ENV['RACK_ENV'] = ENV['RAILS_ENV'] = environment
144
+ ENV["RACK_ENV"] = ENV["RAILS_ENV"] = environment
144
145
  else
145
- self.environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
146
+ self.environment = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
146
147
  end
147
148
  end
148
149
 
@@ -158,9 +159,10 @@ module RocketJob
158
159
  end
159
160
 
160
161
  # Eager load files in jobs folder
161
- def self.eager_load_jobs(job_path = 'jobs')
162
+ def self.eager_load_jobs(job_path = "jobs")
162
163
  Pathname.glob("#{job_path}/**/*.rb").each do |path|
163
164
  next if path.directory?
165
+
164
166
  logger.debug "Loading #{path}"
165
167
  require path.expand_path.to_s
166
168
  end
@@ -169,7 +171,7 @@ module RocketJob
169
171
  def perform_list_servers(filter)
170
172
  return list_the_servers(filter) unless refresh
171
173
 
172
- while true
174
+ loop do
173
175
  list_the_servers(filter)
174
176
  sleep(refresh)
175
177
  puts
@@ -177,10 +179,10 @@ module RocketJob
177
179
  end
178
180
 
179
181
  def list_the_servers(filter)
180
- format = "%50.50s %20.20s %20.20s %20.20s %10.10s"
181
- puts format % %w[Server\ Name Workers(Current/Max) Started Heartbeat State]
182
+ layout = "%50.50s %20.20s %20.20s %20.20s %10.10s"
183
+ puts format(layout, "Server Name", "Workers(Current/Max)", "Started", "Heartbeat", "State")
182
184
  header = "=" * 50
183
- puts format % [header, header, header, header, header]
185
+ puts format(layout, header, header, header, header, header)
184
186
  query = filter == :all ? RocketJob::Server.all : RocketJob::Server.where(name: /#{filter}/)
185
187
  query.each do |server|
186
188
  workers = "#{server&.heartbeat&.workers}/#{server.max_workers}"
@@ -188,14 +190,14 @@ module RocketJob
188
190
  started = "#{RocketJob.seconds_as_duration(duration)} ago"
189
191
  duration = Time.now - (server&.heartbeat&.updated_at || Time.now)
190
192
  heartbeat = "#{RocketJob.seconds_as_duration(duration)} ago"
191
- puts format % [server.name, workers, started, heartbeat, server.state]
193
+ puts format(layout, server.name, workers, started, heartbeat, server.state)
192
194
  end
193
195
  0
194
196
  end
195
197
 
196
198
  def perform_server_action(server_name, action)
197
199
  server_ids(server_name).each { |server_id| RocketJob::Subscribers::Server.publish(action, server_id: server_id) }
198
- #RocketJob::Subscribers::Worker.publish(:stop, worker_id: 1, server_id: RocketJob::Server.running.last.id)
200
+ # RocketJob::Subscribers::Worker.publish(:stop, worker_id: 1, server_id: RocketJob::Server.running.last.id)
199
201
  0
200
202
  end
201
203
 
@@ -219,6 +221,7 @@ module RocketJob
219
221
  if pid
220
222
  server = RocketJob::Server.where(name: server_name).first
221
223
  raise(ArgumentError, "No server with exact name: #{server_name} was found.") unless server
224
+
222
225
  return [server.id]
223
226
  end
224
227
 
@@ -230,90 +233,90 @@ module RocketJob
230
233
 
231
234
  # Parse command line options placing results in the corresponding instance variables
232
235
  def parse(argv)
233
- parser = OptionParser.new do |o|
234
- o.on('-n', '--name NAME', 'Unique Name of this server (Default: host_name:PID)') do |arg|
236
+ parser = OptionParser.new do |o|
237
+ o.on("-n", "--name NAME", "Unique Name of this server (Default: host_name:PID)") do |arg|
235
238
  Config.name = arg
236
239
  end
237
- o.on('-w', '--workers COUNT', 'Number of workers (threads) to start') do |arg|
240
+ o.on("-w", "--workers COUNT", "Number of workers (threads) to start") do |arg|
238
241
  @max_workers = arg.to_i
239
242
  end
240
- o.on('--include REGEXP', 'Limit this server to only those job classes that match this regular expression (case-insensitive). Example: "DirmonJob|WeeklyReportJob"') do |arg|
243
+ o.on("--include REGEXP", 'Limit this server to only those job classes that match this regular expression (case-insensitive). Example: "DirmonJob|WeeklyReportJob"') do |arg|
241
244
  @include_filter = Regexp.new(arg, true)
242
245
  end
243
- o.on('-F', '--filter REGEXP', 'DEPRECATED. Use --include') do |arg|
244
- warn '-F and --filter are deprecated, use --include'
246
+ o.on("-F", "--filter REGEXP", "DEPRECATED. Use --include") do |arg|
247
+ warn "-F and --filter are deprecated, use --include"
245
248
  @include_filter = Regexp.new(arg, true)
246
249
  end
247
- o.on('-E', '--exclude REGEXP', 'Prevent this server from working on any job classes that match this regular expression (case-insensitive). Example: "DirmonJob|WeeklyReportJob"') do |arg|
250
+ o.on("-E", "--exclude REGEXP", 'Prevent this server from working on any job classes that match this regular expression (case-insensitive). Example: "DirmonJob|WeeklyReportJob"') do |arg|
248
251
  @exclude_filter = Regexp.new(arg, true)
249
252
  end
250
- o.on('-W', '--where JSON', "Limit this server instance to the supplied mongo query filter. Supply as a string in JSON format. Example: '{\"priority\":{\"$lte\":25}}'") do |arg|
253
+ o.on("-W", "--where JSON", "Limit this server instance to the supplied mongo query filter. Supply as a string in JSON format. Example: '{\"priority\":{\"$lte\":25}}'") do |arg|
251
254
  @where_filter = JSON.parse(arg)
252
255
  end
253
- o.on('-q', '--quiet', 'Do not write to stdout, only to logfile. Necessary when running as a daemon') do
256
+ o.on("-q", "--quiet", "Do not write to stdout, only to logfile. Necessary when running as a daemon") do
254
257
  @quiet = true
255
258
  end
256
- o.on('-d', '--dir DIR', 'Directory containing Rails app, if not current directory') do |arg|
259
+ o.on("-d", "--dir DIR", "Directory containing Rails app, if not current directory") do |arg|
257
260
  @directory = arg
258
261
  end
259
- o.on('-e', '--environment ENVIRONMENT', 'The environment to run the app on (Default: RAILS_ENV || RACK_ENV || development)') do |arg|
262
+ o.on("-e", "--environment ENVIRONMENT", "The environment to run the app on (Default: RAILS_ENV || RACK_ENV || development)") do |arg|
260
263
  @environment = arg
261
264
  end
262
- o.on('-l', '--log_level trace|debug|info|warn|error|fatal', 'The log level to use') do |arg|
265
+ o.on("-l", "--log_level trace|debug|info|warn|error|fatal", "The log level to use") do |arg|
263
266
  @log_level = arg
264
267
  end
265
- o.on('-f', '--log_file FILE_NAME', 'The log file to write to. Default: log/<environment>.log') do |arg|
268
+ o.on("-f", "--log_file FILE_NAME", "The log file to write to. Default: log/<environment>.log") do |arg|
266
269
  @log_file = arg
267
270
  end
268
- o.on('--pidfile PATH', 'Use PATH as a pidfile') do |arg|
271
+ o.on("--pidfile PATH", "Use PATH as a pidfile") do |arg|
269
272
  @pidfile = arg
270
273
  end
271
- o.on('-m', '--mongo MONGO_CONFIG_FILE_NAME', 'Path and filename of config file. Default: config/mongoid.yml') do |arg|
274
+ o.on("-m", "--mongo MONGO_CONFIG_FILE_NAME", "Path and filename of config file. Default: config/mongoid.yml") do |arg|
272
275
  @mongo_config = arg
273
276
  end
274
- o.on('-s', '--symmetric-encryption SYMMETRIC_ENCRYPTION_CONFIG_FILE_NAME', 'Path and filename of Symmetric Encryption config file. Default: config/symmetric-encryption.yml') do |arg|
277
+ o.on("-s", "--symmetric-encryption SYMMETRIC_ENCRYPTION_CONFIG_FILE_NAME", "Path and filename of Symmetric Encryption config file. Default: config/symmetric-encryption.yml") do |arg|
275
278
  @symmetric_encryption_config = arg
276
279
  end
277
- o.on('--list [FILTER]', "List active servers. Supply either an exact server name or a partial name as a filter.") do |filter|
280
+ o.on("--list [FILTER]", "List active servers. Supply either an exact server name or a partial name as a filter.") do |filter|
278
281
  @quiet = true
279
282
  @server = false
280
283
  @list_servers = filter || :all
281
284
  end
282
- o.on('--refresh [SECONDS]', "When listing active servers, update the list by this number of seconds. Defaults to every 1 second.") do |seconds|
285
+ o.on("--refresh [SECONDS]", "When listing active servers, update the list by this number of seconds. Defaults to every 1 second.") do |seconds|
283
286
  @refresh = (seconds || 1).to_s.to_f
284
287
  end
285
- o.on('--stop [SERVER_NAME]', "Send event to stop a server once all in-process workers have completed. Optionally supply the complete or partial name of the server(s) to stop. Default: All servers.") do |server_name|
288
+ o.on("--stop [SERVER_NAME]", "Send event to stop a server once all in-process workers have completed. Optionally supply the complete or partial name of the server(s) to stop. Default: All servers.") do |server_name|
286
289
  @quiet = true
287
290
  @server = false
288
291
  @stop_server = server_name || :all
289
292
  end
290
- o.on('--kill [SERVER_NAME]', "Send event to hard kill a server. Optionally supply the complete or partial name of the server(s) to kill. Default: All servers.") do |server_name|
293
+ o.on("--kill [SERVER_NAME]", "Send event to hard kill a server. Optionally supply the complete or partial name of the server(s) to kill. Default: All servers.") do |server_name|
291
294
  @quiet = true
292
295
  @server = false
293
296
  @kill_server = server_name || :all
294
297
  end
295
- o.on('--pause [SERVER_NAME]', "Send event to pause a server. Optionally supply the complete or partial name of the server(s) to pause. Default: All servers.") do |server_name|
298
+ o.on("--pause [SERVER_NAME]", "Send event to pause a server. Optionally supply the complete or partial name of the server(s) to pause. Default: All servers.") do |server_name|
296
299
  @quiet = true
297
300
  @server = false
298
301
  @pause_server = server_name || :all
299
302
  end
300
- o.on('--resume [SERVER_NAME]', "Send event to resume a server. Optionally supply the complete or partial name of the server(s) to resume. Default: All servers.") do |server_name|
303
+ o.on("--resume [SERVER_NAME]", "Send event to resume a server. Optionally supply the complete or partial name of the server(s) to resume. Default: All servers.") do |server_name|
301
304
  @quiet = true
302
305
  @server = false
303
306
  @resume_server = server_name || :all
304
307
  end
305
- o.on('--dump [SERVER_NAME]', "Send event for a server to send a worker thread dump to its log file. Optionally supply the complete or partial name of the server(s). Default: All servers.") do |server_name|
308
+ o.on("--dump [SERVER_NAME]", "Send event for a server to send a worker thread dump to its log file. Optionally supply the complete or partial name of the server(s). Default: All servers.") do |server_name|
306
309
  @quiet = true
307
310
  @server = false
308
311
  @thread_dump = server_name || :all
309
312
  end
310
- o.on('-v', '--version', 'Print the version information') do
313
+ o.on("-v", "--version", "Print the version information") do
311
314
  puts "Rocket Job v#{RocketJob::VERSION}"
312
315
  exit 1
313
316
  end
314
317
  end
315
- parser.banner = 'rocketjob <options>'
316
- parser.on_tail '-h', '--help', 'Show help' do
318
+ parser.banner = "rocketjob <options>"
319
+ parser.on_tail "-h", "--help", "Show help" do
317
320
  puts parser
318
321
  exit 1
319
322
  end
@@ -1,4 +1,4 @@
1
- require 'yaml'
1
+ require "yaml"
2
2
  module RocketJob
3
3
  # Rocket Job Configuration
4
4
  class Config
@@ -72,8 +72,8 @@ module RocketJob
72
72
  self.where_filter = nil
73
73
 
74
74
  # Configure Mongoid
75
- def self.load!(environment = 'development', file_name = nil, encryption_file_name = nil)
76
- config_file = file_name ? Pathname.new(file_name) : Pathname.pwd.join('config/mongoid.yml')
75
+ def self.load!(environment = "development", file_name = nil, encryption_file_name = nil)
76
+ config_file = file_name ? Pathname.new(file_name) : Pathname.pwd.join("config/mongoid.yml")
77
77
 
78
78
  raise(ArgumentError, "Mongo Configuration file: #{config_file} not found") unless config_file.file?
79
79
 
@@ -84,7 +84,7 @@ module RocketJob
84
84
  if encryption_file_name
85
85
  Pathname.new(encryption_file_name)
86
86
  else
87
- Pathname.pwd.join('config/symmetric-encryption.yml')
87
+ Pathname.pwd.join("config/symmetric-encryption.yml")
88
88
  end
89
89
 
90
90
  return unless config_file.file?
@@ -97,14 +97,12 @@ module RocketJob
97
97
  # include_filter, exclude_filter, and where_filter.
98
98
  # Returns nil if no filter should be applied.
99
99
  def self.filter
100
- if include_filter && exclude_filter
101
- raise(ArgumentError, 'Cannot supply both an include_filter and an exclude_filter')
102
- end
100
+ raise(ArgumentError, "Cannot supply both an include_filter and an exclude_filter") if include_filter && exclude_filter
103
101
 
104
102
  filter = where_filter
105
- (filter ||= {})['_type'] = include_filter if include_filter
106
- (filter ||= {})['_type'] = {'$not' => exclude_filter} if exclude_filter
107
- filter
103
+ (filter ||= {})["_type"] = include_filter if include_filter
104
+ (filter ||= {})["_type"] = {"$not" => exclude_filter} if exclude_filter
105
+ filter&.dup
108
106
  end
109
107
  end
110
108
  end
@@ -1,5 +1,5 @@
1
- require 'concurrent'
2
- require 'fileutils'
1
+ require "concurrent"
2
+ require "fileutils"
3
3
  module RocketJob
4
4
  class DirmonEntry
5
5
  include Plugins::Document
@@ -8,9 +8,9 @@ module RocketJob
8
8
  # The default archive directory that is used when the job being queued does not respond
9
9
  # to #upload, and does not have an `archive_directory` specified in this entry
10
10
  class_attribute :default_archive_directory
11
- self.default_archive_directory = 'archive'.freeze
11
+ self.default_archive_directory = "archive".freeze
12
12
 
13
- store_in collection: 'rocket_job.dirmon_entries'
13
+ store_in collection: "rocket_job.dirmon_entries"
14
14
 
15
15
  # User defined name used to identify this DirmonEntry in the Web Interface.
16
16
  field :name, type: String
@@ -55,7 +55,7 @@ module RocketJob
55
55
  field :archive_directory, type: String, default: default_archive_directory
56
56
 
57
57
  # If this DirmonEntry is in the failed state, exception contains the cause
58
- embeds_one :exception, class_name: 'RocketJob::JobException'
58
+ embeds_one :exception, class_name: "RocketJob::JobException"
59
59
 
60
60
  # The maximum number of files that should ever match during a single poll of the pattern.
61
61
  #
@@ -73,7 +73,7 @@ module RocketJob
73
73
  field :state, type: Symbol, default: :pending
74
74
 
75
75
  # Unique index on pattern to help prevent two entries from scanning the same files
76
- index({pattern: 1}, background: true, unique: true, drop_dups: true)
76
+ index({pattern: 1}, background: true, unique: true)
77
77
 
78
78
  before_validation :strip_whitespace
79
79
  validates_presence_of :pattern, :job_class_name, :archive_directory
@@ -175,8 +175,8 @@ module RocketJob
175
175
  # # => {}
176
176
  def self.counts_by_state
177
177
  counts = {}
178
- collection.aggregate([{'$group' => {_id: '$state', count: {'$sum' => 1}}}]).each do |result|
179
- counts[result['_id'].to_sym] = result['count']
178
+ collection.aggregate([{"$group" => {_id: "$state", count: {"$sum" => 1}}}]).each do |result|
179
+ counts[result["_id"].to_sym] = result["count"]
180
180
  end
181
181
  counts
182
182
  end
@@ -213,7 +213,7 @@ module RocketJob
213
213
  exception.worker_name = worker_name
214
214
  else
215
215
  build_exception(
216
- class_name: 'RocketJob::DirmonEntryException',
216
+ class_name: "RocketJob::DirmonEntryException",
217
217
  message: exc_or_message,
218
218
  backtrace: [],
219
219
  worker_name: worker_name
@@ -224,6 +224,7 @@ module RocketJob
224
224
  # Returns the Job to be created.
225
225
  def job_class
226
226
  return if job_class_name.nil?
227
+
227
228
  job_class_name.constantize
228
229
  rescue NameError
229
230
  nil
@@ -245,7 +246,7 @@ module RocketJob
245
246
  )
246
247
 
247
248
  logger.info(
248
- message: 'Created RocketJob::Jobs::UploadFileJob',
249
+ message: "Created RocketJob::Jobs::UploadFileJob",
249
250
  payload: {
250
251
  dirmon_entry_name: name,
251
252
  upload_file_name: archive_path.to_s,
@@ -282,6 +283,7 @@ module RocketJob
282
283
  def job_is_a_rocket_job
283
284
  klass = job_class
284
285
  return if job_class_name.nil? || klass&.ancestors&.include?(RocketJob::Job)
286
+
285
287
  errors.add(:job_class_name, "Job #{job_class_name} must be defined and inherit from RocketJob::Job")
286
288
  end
287
289
 
@@ -292,6 +294,7 @@ module RocketJob
292
294
 
293
295
  properties.each_pair do |k, _v|
294
296
  next if klass.public_method_defined?("#{k}=".to_sym)
297
+
295
298
  errors.add(:properties, "Unknown Property: Attempted to set a value for #{k.inspect} which is not allowed on the job #{job_class_name}")
296
299
  end
297
300
  end
@@ -1,4 +1,4 @@
1
- require 'concurrent-ruby'
1
+ require "concurrent-ruby"
2
2
 
3
3
  module RocketJob
4
4
  # RocketJob::Event
@@ -10,7 +10,7 @@ module RocketJob
10
10
  include Plugins::Document
11
11
  include Mongoid::Timestamps
12
12
 
13
- ALL_EVENTS = '*'.freeze
13
+ ALL_EVENTS = "*".freeze
14
14
 
15
15
  # Capped collection long polling interval.
16
16
  class_attribute :long_poll_seconds, instance_accessor: false
@@ -42,7 +42,7 @@ module RocketJob
42
42
 
43
43
  validates_presence_of :name
44
44
 
45
- store_in collection: 'rocket_job.events'
45
+ store_in collection: "rocket_job.events"
46
46
  index({created_at: 1}, background: true)
47
47
 
48
48
  # Add a subscriber for its events.
@@ -84,14 +84,14 @@ module RocketJob
84
84
  # Indefinitely tail the capped collection looking for new events.
85
85
  # time: the start time from which to start looking for new events.
86
86
  def self.listener(time: @load_time)
87
- Thread.current.name = 'rocketjob event'
87
+ Thread.current.name = "rocketjob event"
88
88
  create_capped_collection
89
89
 
90
- logger.info('Event listener started')
90
+ logger.info("Event listener started")
91
91
  tail_capped_collection(time) { |event| process_event(event) }
92
- rescue Exception => exc
93
- logger.error('#listener Event listener is terminating due to unhandled exception', exc)
94
- raise(exc)
92
+ rescue Exception => e
93
+ logger.error("#listener Event listener is terminating due to unhandled exception", e)
94
+ raise(e)
95
95
  end
96
96
 
97
97
  # Create the capped collection only if it does not exist.
@@ -117,13 +117,13 @@ module RocketJob
117
117
 
118
118
  def self.tail_capped_collection(time)
119
119
  with(socket_timeout: long_poll_seconds + 10) do
120
- filter = {created_at: {'$gt' => time}}
120
+ filter = {created_at: {"$gt" => time}}
121
121
  collection.
122
122
  find(filter).
123
123
  await_data.
124
124
  cursor_type(:tailable_await).
125
125
  max_await_time_ms(long_poll_seconds * 1000).
126
- sort('$natural' => 1).
126
+ sort("$natural" => 1).
127
127
  each do |doc|
128
128
  event = Mongoid::Factory.from_db(Event, doc)
129
129
  # Recovery will occur from after the last message read
@@ -131,14 +131,14 @@ module RocketJob
131
131
  yield(event)
132
132
  end
133
133
  end
134
- rescue Mongo::Error::SocketError, Mongo::Error::SocketTimeoutError, Mongo::Error::OperationFailure, Timeout::Error => exc
135
- logger.info("Creating a new cursor and trying again: #{exc.class.name} #{exc.message}")
134
+ rescue Mongo::Error::SocketError, Mongo::Error::SocketTimeoutError, Mongo::Error::OperationFailure, Timeout::Error => e
135
+ logger.info("Creating a new cursor and trying again: #{e.class.name} #{e.message}")
136
136
  retry
137
137
  end
138
138
 
139
139
  # Process a new event, calling registered subscribers.
140
140
  def self.process_event(event)
141
- logger.info('Event Received', event.attributes)
141
+ logger.info("Event Received", event.attributes)
142
142
 
143
143
  if @subscribers.key?(event.name)
144
144
  @subscribers[event.name].each { |subscriber| subscriber.process_action(event.action, event.parameters) }
@@ -147,8 +147,8 @@ module RocketJob
147
147
  if @subscribers.key?(ALL_EVENTS)
148
148
  @subscribers[ALL_EVENTS].each { |subscriber| subscriber.process_event(event.name, event.action, event.parameters) }
149
149
  end
150
- rescue StandardError => exc
151
- logger.error('Unknown subscriber. Continuing..', exc)
150
+ rescue StandardError => e
151
+ logger.error("Unknown subscriber. Continuing..", e)
152
152
  end
153
153
 
154
154
  def self.collection_exists?
@@ -157,7 +157,7 @@ module RocketJob
157
157
 
158
158
  # Convert a non-capped collection to capped
159
159
  def self.convert_to_capped_collection(size)
160
- collection.database.command('convertToCapped' => collection_name.to_s, 'size' => size)
160
+ collection.database.command("convertToCapped" => collection_name.to_s, "size" => size)
161
161
  end
162
162
  end
163
163
  end