rocketjob 2.1.3 → 3.0.0.alpha

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +36 -0
  3. data/lib/rocket_job/active_server.rb +48 -0
  4. data/lib/rocket_job/cli.rb +29 -17
  5. data/lib/rocket_job/config.rb +19 -31
  6. data/lib/rocket_job/dirmon_entry.rb +15 -45
  7. data/lib/rocket_job/extensions/mongo/logging.rb +26 -0
  8. data/lib/rocket_job/extensions/rocket_job_adapter.rb +3 -5
  9. data/lib/rocket_job/heartbeat.rb +18 -23
  10. data/lib/rocket_job/job.rb +0 -1
  11. data/lib/rocket_job/job_exception.rb +11 -13
  12. data/lib/rocket_job/jobs/dirmon_job.rb +8 -8
  13. data/lib/rocket_job/jobs/housekeeping_job.rb +13 -15
  14. data/lib/rocket_job/performance.rb +5 -5
  15. data/lib/rocket_job/plugins/cron.rb +3 -10
  16. data/lib/rocket_job/plugins/document.rb +58 -33
  17. data/lib/rocket_job/plugins/job/model.rb +43 -71
  18. data/lib/rocket_job/plugins/job/persistence.rb +7 -63
  19. data/lib/rocket_job/plugins/job/worker.rb +24 -26
  20. data/lib/rocket_job/plugins/processing_window.rb +6 -9
  21. data/lib/rocket_job/plugins/retry.rb +3 -8
  22. data/lib/rocket_job/plugins/singleton.rb +1 -1
  23. data/lib/rocket_job/plugins/state_machine.rb +1 -7
  24. data/lib/rocket_job/server.rb +352 -0
  25. data/lib/rocket_job/version.rb +1 -1
  26. data/lib/rocket_job/worker.rb +46 -336
  27. data/lib/rocketjob.rb +5 -4
  28. data/test/config/mongoid.yml +88 -0
  29. data/test/config_test.rb +1 -1
  30. data/test/dirmon_entry_test.rb +15 -79
  31. data/test/dirmon_job_test.rb +6 -6
  32. data/test/job_test.rb +2 -2
  33. data/test/plugins/job/callbacks_test.rb +40 -32
  34. data/test/plugins/job/defaults_test.rb +10 -8
  35. data/test/plugins/job/model_test.rb +1 -3
  36. data/test/plugins/job/persistence_test.rb +11 -13
  37. data/test/plugins/job/worker_test.rb +45 -26
  38. data/test/plugins/processing_window_test.rb +4 -4
  39. data/test/plugins/restart_test.rb +11 -12
  40. data/test/plugins/state_machine_event_callbacks_test.rb +20 -18
  41. data/test/plugins/state_machine_test.rb +5 -5
  42. data/test/test_helper.rb +4 -1
  43. metadata +15 -29
  44. data/lib/rocket_job/extensions/mongo.rb +0 -23
  45. data/lib/rocket_job/extensions/mongo_mapper.rb +0 -30
  46. data/lib/rocket_job/plugins/job/defaults.rb +0 -40
  47. data/test/config/mongo.yml +0 -46
@@ -2,46 +2,41 @@
2
2
  module RocketJob
3
3
  # Heartbeat
4
4
  #
5
- # Information from the worker as at it's last heartbeat
5
+ # Information from the server as at it's last heartbeat
6
6
  class Heartbeat
7
- include MongoMapper::EmbeddedDocument
7
+ include Plugins::Document
8
8
 
9
- embedded_in :worker
10
-
11
- # @formatter:off
12
- # Time of the last heartbeat received from this worker
13
- key :updated_at, Time
9
+ # Time of the last heartbeat received from this server
10
+ field :updated_at, type: Time
14
11
 
15
12
  # Number of threads running as at the last heartbeat interval
16
- key :active_threads, Integer
13
+ field :active_threads, type: Integer
17
14
  # Number of threads in the pool
18
- # This number should grow and shrink between 1 and :max_threads
19
- key :current_threads, Integer
15
+ # This number should grow and shrink between 1 and :max_workers
16
+ field :current_threads, type: Integer
20
17
 
21
18
  #
22
- # Process Information
19
+ # Process Information. Future.
23
20
  #
24
21
 
25
- # Percentage utilization for the worker process alone
26
- key :process_cpu, Integer
27
- # Kilo Bytes used by the worker process (Virtual & Physical)
28
- key :process_mem_phys_kb, Integer
29
- key :process_mem_virt_kb, Integer
22
+ # Percentage utilization for the server process alone
23
+ #field :process_cpu, type: Integer
24
+ # Kilo Bytes used by the server process (Virtual & Physical)
25
+ #field :process_mem_phys_kb, type: Integer
26
+ #field :process_mem_virt_kb, type: Integer
30
27
 
31
28
  #
32
- # System Information
29
+ # System Information. Future.
33
30
  #
34
31
 
35
32
  # Percentage utilization for the host machine
36
- key :host_cpu, Integer
33
+ #field :host_cpu, type: Integer
37
34
  # Kilo Bytes Available on the host machine (Physical)
38
- key :host_mem_avail_phys_kbytes, Float
39
- key :host_mem_avail_virt_kbytes, Float
35
+ #field :host_mem_avail_phys_kbytes, type: Float
36
+ #field :host_mem_avail_virt_kbytes, type: Float
40
37
 
41
38
  # If available
42
- key :load_average, Float
43
- # @formatter:on
44
-
39
+ #field :load_average, type: Float
45
40
  end
46
41
  end
47
42
 
@@ -11,6 +11,5 @@ module RocketJob
11
11
  include Plugins::StateMachine
12
12
  include Plugins::Job::StateMachine
13
13
  include Plugins::Job::Worker
14
- include Plugins::Job::Defaults
15
14
  end
16
15
  end
@@ -1,28 +1,26 @@
1
1
  # encoding: UTF-8
2
2
  module RocketJob
3
- # Heartbeat
4
- #
5
- # Information from the worker as at it's last heartbeat
6
3
  class JobException
7
- include MongoMapper::EmbeddedDocument
4
+ include Plugins::Document
5
+
6
+ embedded_in :job, inverse_of: :exception
7
+ embedded_in :slice, inverse_of: :exception
8
+ embedded_in :dirmon_entry, inverse_of: :exception
8
9
 
9
- # @formatter:off
10
10
  # Name of the exception class
11
- key :class_name, String
11
+ field :class_name, type: String
12
12
 
13
13
  # Exception message
14
- key :message, String
14
+ field :message, type: String
15
15
 
16
16
  # Exception Backtrace [Array<String>]
17
- key :backtrace, Array
17
+ field :backtrace, type: Array, default: []
18
18
 
19
- # Name of the worker on which this exception occurred
20
- key :worker_name, String
19
+ # Name of the server on which this exception occurred
20
+ field :worker_name, type: String
21
21
 
22
22
  # The record within which this exception occurred
23
- key :record_number, Integer
24
-
25
- # @formatter:on
23
+ field :record_number, type: Integer
26
24
 
27
25
  # Returns [JobException] built from the supplied exception
28
26
  def self.from_exception(exc)
@@ -15,10 +15,11 @@ module RocketJob
15
15
 
16
16
  # * Otherwise, the file is moved to the supplied archive_directory (defaults to
17
17
  # `_archive` in the same folder as the file itself. The absolute path and
18
- # file name of the archived file is passed into the job as it's first argument.
18
+ # file name of the archived file is passed into the job as either
19
+ # `upload_file_name` or `full_file_name`.
19
20
 
20
21
  # Note:
21
- # - Jobs that do not implement #upload _must_ have a Hash as the first argument
22
+ # - Jobs that do not implement #upload _must_ have either `upload_file_name` or `full_file_name` as an attribute.
22
23
  #
23
24
  # With RocketJob Pro, the file is automatically uploaded into the job itself
24
25
  # using the job's #upload method, after which the file is archived or deleted
@@ -39,13 +40,12 @@ module RocketJob
39
40
  # Start a new job when this one completes, fails, or aborts
40
41
  include RocketJob::Plugins::Restart
41
42
 
42
- rocket_job do |job|
43
- job.priority = 40
44
- end
43
+ self.priority = 40
45
44
 
46
45
  # Number of seconds between directory scans. Default 5 mins
47
- key :check_seconds, Float, default: 300.0
48
- key :previous_file_names, Hash # Hash[file_name, size]
46
+ field :check_seconds, type: Float, default: 300.0
47
+ # Hash[file_name, size]
48
+ field :previous_file_names, type: Hash, default: {}
49
49
 
50
50
  before_create :set_run_at
51
51
 
@@ -68,7 +68,7 @@ module RocketJob
68
68
  # since the last run
69
69
  def check_directories
70
70
  new_file_names = {}
71
- DirmonEntry.where(state: :enabled).each do |entry|
71
+ DirmonEntry.enabled.each do |entry|
72
72
  entry.each do |pathname|
73
73
  # BSON Keys cannot contain periods
74
74
  key = pathname.to_s.gsub('.', '_')
@@ -30,26 +30,24 @@ module RocketJob
30
30
  include RocketJob::Plugins::Cron
31
31
  include RocketJob::Plugins::Singleton
32
32
 
33
- rocket_job do |job|
34
- job.priority = 50
35
- job.description = 'Cleans out historical jobs'
36
- job.cron_schedule = '0 0 * * * America/New_York'
37
- end
33
+ self.priority = 50
34
+ self.description = 'Cleans out historical jobs'
35
+ self.cron_schedule = '0 0 * * * America/New_York'
38
36
 
39
37
  # Retention intervals in seconds
40
38
  # Set to nil to not
41
- key :aborted_retention, Integer, default: 7.days
42
- key :completed_retention, Integer, default: 7.days
43
- key :failed_retention, Integer, default: 14.days
44
- key :paused_retention, Integer, default: 90.days
45
- key :queued_retention, Integer
39
+ field :aborted_retention, Integer, default: 7.days
40
+ field :completed_retention, Integer, default: 7.days
41
+ field :failed_retention, Integer, default: 14.days
42
+ field :paused_retention, Integer, default: 90.days
43
+ field :queued_retention, Integer
46
44
 
47
45
  def perform
48
- RocketJob::Job.where(state: :aborted, created_at: {'$lte' => aborted_retention.ago}).destroy_all if aborted_retention
49
- RocketJob::Job.where(state: :completed, created_at: {'$lte' => completed_retention.ago}).destroy_all if completed_retention
50
- RocketJob::Job.where(state: :failed, created_at: {'$lte' => failed_retention.ago}).destroy_all if failed_retention
51
- RocketJob::Job.where(state: :paused, created_at: {'$lte' => paused_retention.ago}).destroy_all if paused_retention
52
- RocketJob::Job.where(state: :queued, created_at: {'$lte' => queued_retention.ago}).destroy_all if queued_retention
46
+ RocketJob::Job.aborted.where(created_at: {'$lte' => aborted_retention.ago}).destroy_all if aborted_retention
47
+ RocketJob::Job.completed.where(created_at: {'$lte' => completed_retention.ago}).destroy_all if completed_retention
48
+ RocketJob::Job.failed.where(created_at: {'$lte' => failed_retention.ago}).destroy_all if failed_retention
49
+ RocketJob::Job.paused.where(created_at: {'$lte' => paused_retention.ago}).destroy_all if paused_retention
50
+ RocketJob::Job.queued.where(created_at: {'$lte' => queued_retention.ago}).destroy_all if queued_retention
53
51
  end
54
52
 
55
53
  end
@@ -15,12 +15,12 @@ module RocketJob
15
15
  end
16
16
 
17
17
  def run_test_case(count = self.count)
18
- self.worker_processes = RocketJob::Worker.count
18
+ self.worker_processes = RocketJob::Server.count
19
19
  raise 'Please start workers before starting the performance test' if worker_processes == 0
20
20
 
21
21
  self.worker_processes = 0
22
22
  self.worker_threads = 0
23
- RocketJob::Worker.where(state: :running).each do |worker_process|
23
+ RocketJob::Server.running.each do |worker_process|
24
24
  unless worker_process.zombie?
25
25
  self.worker_processes += 1
26
26
  self.worker_threads += worker_process.heartbeat.current_threads
@@ -29,7 +29,7 @@ module RocketJob
29
29
  puts "Running: #{worker_threads} workers, distributed across #{worker_processes} processes"
30
30
 
31
31
  puts 'Waiting for workers to pause'
32
- RocketJob::Worker.pause_all
32
+ RocketJob::Server.pause_all
33
33
  RocketJob::Jobs::SimpleJob.delete_all
34
34
  sleep 15
35
35
 
@@ -39,7 +39,7 @@ module RocketJob
39
39
  last = RocketJob::Jobs::SimpleJob.create(priority: 100, destroy_on_complete: false)
40
40
 
41
41
  puts 'Resuming workers'
42
- RocketJob::Worker.resume_all
42
+ RocketJob::Server.resume_all
43
43
 
44
44
  while (!last.reload.completed?)
45
45
  sleep 3
@@ -63,7 +63,7 @@ module RocketJob
63
63
  o.on('-c', '--count COUNT', 'Count of jobs to enqueue') do |arg|
64
64
  self.count = arg.to_i
65
65
  end
66
- o.on('-m', '--mongo MONGO_CONFIG_FILE_NAME', 'Location of mongo.yml config file') do |arg|
66
+ o.on('-m', '--mongo MONGO_CONFIG_FILE_NAME', 'Path and filename of config file. Default: config/mongoid.yml') do |arg|
67
67
  self.mongo_config = arg
68
68
  end
69
69
  o.on('-e', '--environment ENVIRONMENT', 'The environment to run the app on (Default: RAILS_ENV || RACK_ENV || development)') do |arg|
@@ -40,9 +40,7 @@ module RocketJob
40
40
  # include RocketJob::Plugins::Cron
41
41
  #
42
42
  # # Set the default cron_schedule
43
- # rocket_job do |job|
44
- # job.cron_schedule = "* 1 * * * UTC"
45
- # end
43
+ # self.cron_schedule = "* 1 * * * UTC"
46
44
  #
47
45
  # def perform
48
46
  # puts "DONE"
@@ -70,9 +68,7 @@ module RocketJob
70
68
  # include RocketJob::Plugins::Singleton
71
69
  #
72
70
  # # Set the default cron_schedule
73
- # rocket_job do |job|
74
- # job.cron_schedule = "* 1 * * * UTC"
75
- # end
71
+ # self.cron_schedule = "* 1 * * * UTC"
76
72
  #
77
73
  # def perform
78
74
  # puts "DONE"
@@ -105,10 +101,7 @@ module RocketJob
105
101
  included do
106
102
  include Restart
107
103
 
108
- key :cron_schedule, String
109
-
110
- # Make cron_schedule editable for scheduled jobs
111
- public_rocket_job_properties :cron_schedule
104
+ field :cron_schedule, type: String, class_attribute: true, user_editable: true
112
105
 
113
106
  before_create :rocket_job_set_run_at
114
107
 
@@ -1,57 +1,82 @@
1
1
  # encoding: UTF-8
2
2
  require 'active_support/concern'
3
- require 'mongo'
4
- require 'mongo_ha'
5
- begin
6
- require 'active_model/serializers/xml'
7
- rescue LoadError
8
- raise "Please add gem 'activemodel-serializers-xml' to Gemfile to support Active Model V5"
9
- end
10
- require 'mongo_mapper'
11
3
 
12
4
  module RocketJob
13
5
  module Plugins
14
6
  # Base class for storing models in MongoDB
15
7
  module Document
16
8
  extend ActiveSupport::Concern
17
- include MongoMapper::Document
9
+ include Mongoid::Document
18
10
 
19
11
  included do
20
- # Prevent data in MongoDB from re-defining the model behavior.
21
- self.static_keys = true
22
-
23
- # Only save changes to this instance to prevent losing
24
- # changes made by other processes or threads.
25
- self.partial_updates = true
12
+ store_in client: 'rocketjob'
26
13
 
27
- # Turn off embedded callbacks. Slow and not used by Jobs.
28
- embedded_callbacks_off
14
+ class_attribute :user_editable_fields, instance_accessor: false
15
+ self.user_editable_fields = []
29
16
  end
30
17
 
31
- # Patch the way MongoMapper reloads a model
32
- def reload
33
- if doc = collection.find_one(:_id => id)
34
- # Clear out keys that are not returned during the reload from MongoDB
35
- (keys.keys - doc.keys).each { |key| send("#{key}=", nil) }
36
- initialize_default_values
37
- load_from_database(doc)
38
- self
39
- else
40
- raise MongoMapper::DocumentNotFound, "Document match #{_id.inspect} does not exist in #{collection.name} collection"
18
+ module ClassMethods
19
+ # Defines all the fields that are accessible on the Document
20
+ # For each field that is defined, a getter and setter will be
21
+ # added as an instance method to the Document.
22
+ #
23
+ # @example Define a field.
24
+ # field :score, :type => Integer, :default => 0
25
+ #
26
+ # @param [ Symbol ] name The name of the field.
27
+ # @param [ Hash ] options The options to pass to the field.
28
+ #
29
+ # @option options [ Class ] :type The type of the field.
30
+ # @option options [ String ] :label The label for the field.
31
+ # @option options [ Object, Proc ] :default The field's default
32
+ # @option options [ Boolean ] :class_attribute Keep the fields default in a class_attribute
33
+ # @option options [ Boolean ] :user_editable Field can be edited by end users in RJMC
34
+ #
35
+ # @return [ Field ] The generated field
36
+ def field(name, options)
37
+ if options.delete(:user_editable) == true
38
+ self.user_editable_fields += [name.to_sym] unless user_editable_fields.include?(name.to_sym)
39
+ end
40
+ if options.delete(:class_attribute) == true
41
+ class_attribute(name, instance_accessor: false)
42
+ if options.has_key?(:default)
43
+ public_send("#{name}=", options[:default])
44
+ end
45
+ options[:default] = lambda { self.class.public_send(name) }
46
+ end
47
+ super(name, options)
48
+ end
49
+
50
+ # V2 Backward compatibility
51
+ # DEPRECATED
52
+ def key(name, type, options = {})
53
+ field(name, options.merge(type: type))
54
+ end
55
+
56
+ # Mongoid does not apply ordering, add sort
57
+ def first
58
+ all.sort('_id' => 1).first
59
+ end
60
+
61
+ # Mongoid does not apply ordering, add sort
62
+ def last
63
+ all.sort('_id' => -1).first
41
64
  end
42
65
  end
43
66
 
44
67
  private
45
68
 
46
- def update_attributes_and_reload(attrs)
47
- if doc = collection.find_and_modify(query: {:_id => id}, update: {'$set' => attrs})
69
+ # Apply changes to this document returning the updated document from the database.
70
+ # Allows other changes to be made on the server that will be loaded.
71
+ def find_and_update(attrs)
72
+ if doc = collection.find(_id: id).find_one_and_update({'$set' => attrs}, return_document: :after)
48
73
  # Clear out keys that are not returned during the reload from MongoDB
49
- (keys.keys - doc.keys).each { |key| send("#{key}=", nil) }
50
- initialize_default_values
51
- load_from_database(doc)
74
+ (fields.keys + embedded_relations.keys - doc.keys).each { |key| send("#{key}=", nil) }
75
+ @attributes = attributes
76
+ apply_defaults
52
77
  self
53
78
  else
54
- raise MongoMapper::DocumentNotFound, "Document match #{_id.inspect} does not exist in #{collection.name} collection"
79
+ raise Mongoid::Error::DocumentNotFound, "Document match #{_id.inspect} does not exist in #{collection.name} collection"
55
80
  end
56
81
  end
57
82
 
@@ -13,10 +13,9 @@ module RocketJob
13
13
  # User definable attributes
14
14
  #
15
15
  # The following attributes are set when the job is created
16
- # @formatter:off
17
16
 
18
17
  # Description for this job instance
19
- key :description, String
18
+ field :description, type: String, class_attribute: true, user_editable: true
20
19
 
21
20
  # Priority of this job as it relates to other jobs [1..100]
22
21
  # 1: Highest Priority
@@ -29,64 +28,47 @@ module RocketJob
29
28
  # In RocketJob Pro, if a SlicedJob is running and a higher priority job
30
29
  # arrives, then the current job will complete the current slices and process
31
30
  # the new higher priority job
32
- key :priority, Integer, default: 50
33
-
34
- # Run this job no earlier than this time
35
- key :run_at, Time
36
-
37
- # If a job has not started by this time, destroy it
38
- key :expires_at, Time
31
+ field :priority, type: Integer, default: 50, class_attribute: true, user_editable: true
39
32
 
40
33
  # When the job completes destroy it from both the database and the UI
41
- key :destroy_on_complete, Boolean, default: true
42
-
43
- # Any user supplied arguments for the method invocation
44
- # All keys must be UTF-8 strings. The values can be any valid BSON type:
45
- # Integer
46
- # Float
47
- # Time (UTC)
48
- # String (UTF-8)
49
- # Array
50
- # Hash
51
- # True
52
- # False
53
- # Symbol
54
- # nil
55
- # Regular Expression
56
- #
57
- # Note: Date is not supported, convert it to a UTC time
58
- key :arguments, Array
34
+ field :destroy_on_complete, type: Boolean, default: true, class_attribute: true
59
35
 
60
36
  # Whether to store the results from this job
61
- key :collect_output, Boolean, default: false
37
+ field :collect_output, type: Boolean, default: false, class_attribute: true
38
+
39
+ # Run this job no earlier than this time
40
+ field :run_at, type: Time
41
+
42
+ # If a job has not started by this time, destroy it
43
+ field :expires_at, type: Time
62
44
 
63
45
  # Raise or lower the log level when calling the job
64
46
  # Can be used to reduce log noise, especially during high volume calls
65
47
  # For debugging a single job can be logged at a low level such as :trace
66
48
  # Levels supported: :trace, :debug, :info, :warn, :error, :fatal
67
- key :log_level, Symbol
49
+ field :log_level, type: Symbol, user_editable: true
68
50
 
69
51
  #
70
52
  # Read-only attributes
71
53
  #
72
54
 
73
55
  # Current state, as set by the state machine. Do not modify this value directly.
74
- key :state, Symbol, default: :queued
56
+ field :state, type: Symbol, default: :queued
75
57
 
76
58
  # When the job was created
77
- key :created_at, Time, default: -> { Time.now }
59
+ field :created_at, type: Time, default: -> { Time.now }
78
60
 
79
61
  # When processing started on this job
80
- key :started_at, Time
62
+ field :started_at, type: Time
81
63
 
82
64
  # When the job completed processing
83
- key :completed_at, Time
65
+ field :completed_at, type: Time
84
66
 
85
67
  # Number of times that this job has failed to process
86
- key :failure_count, Integer, default: 0
68
+ field :failure_count, type: Integer, default: 0
87
69
 
88
70
  # This name of the worker that this job is being processed by, or was processed by
89
- key :worker_name, String
71
+ field :worker_name, type: String
90
72
 
91
73
  #
92
74
  # Values that jobs can update during processing
@@ -94,38 +76,37 @@ module RocketJob
94
76
 
95
77
  # Allow a job to updates its estimated progress
96
78
  # Any integer from 0 to 100
97
- key :percent_complete, Integer, default: 0
79
+ field :percent_complete, type: Integer, default: 0
98
80
 
99
81
  # Store the last exception for this job
100
- one :exception, class_name: 'RocketJob::JobException'
82
+ embeds_one :exception, class_name: 'RocketJob::JobException'
101
83
 
102
84
  # Store the Hash result from this job if collect_output is true,
103
85
  # and the job returned actually returned a Hash, otherwise nil
104
86
  # Not applicable to SlicedJob jobs, since its output is stored in a
105
87
  # separate collection
106
- key :result, Hash
88
+ field :result, type: Hash
107
89
 
108
- # @formatter:on
109
-
110
- # Store all job types in this collection
111
- set_collection_name 'rocket_job.jobs'
90
+ index({state: 1, priority: 1, _id: 1}, background: true)
112
91
 
113
92
  validates_presence_of :state, :failure_count, :created_at
114
93
  validates :priority, inclusion: 1..100
115
94
  validates :log_level, inclusion: SemanticLogger::LEVELS + [nil]
95
+ end
116
96
 
97
+ module ClassMethods
117
98
  # Returns [String] the singular name for this job class
118
99
  #
119
100
  # Example:
120
101
  # job = DataStudyJob.new
121
102
  # job.underscore_name
122
103
  # # => "data_study"
123
- def self.underscore_name
104
+ def underscore_name
124
105
  @underscore_name ||= name.sub(/Job$/, '').underscore
125
106
  end
126
107
 
127
108
  # Allow the collective name for this job class to be overridden
128
- def self.underscore_name=(underscore_name)
109
+ def underscore_name=(underscore_name)
129
110
  @underscore_name = underscore_name
130
111
  end
131
112
 
@@ -135,12 +116,12 @@ module RocketJob
135
116
  # job = DataStudyJob.new
136
117
  # job.human_name
137
118
  # # => "Data Study"
138
- def self.human_name
119
+ def human_name
139
120
  @human_name ||= name.sub(/Job$/, '').titleize
140
121
  end
141
122
 
142
123
  # Allow the human readable job name for this job class to be overridden
143
- def self.human_name=(human_name)
124
+ def human_name=(human_name)
144
125
  @human_name = human_name
145
126
  end
146
127
 
@@ -150,49 +131,40 @@ module RocketJob
150
131
  # job = DataStudyJob.new
151
132
  # job.collective_name
152
133
  # # => "data_studies"
153
- def self.collective_name
134
+ def collective_name
154
135
  @collective_name ||= name.sub(/Job$/, '').pluralize.underscore
155
136
  end
156
137
 
157
138
  # Allow the collective name for this job class to be overridden
158
- def self.collective_name=(collective_name)
139
+ def collective_name=(collective_name)
159
140
  @collective_name = collective_name
160
141
  end
161
142
 
162
143
  # Scope for jobs scheduled to run in the future
163
- def self.scheduled
164
- queued.where(run_at: {'$gt' => Time.now})
144
+ def scheduled
145
+ queued.where(:run_at.gt => Time.now)
165
146
  end
166
147
 
167
148
  # Scope for queued jobs that can run now
168
149
  # I.e. Queued jobs excluding scheduled jobs
169
- def self.queued_now
170
- queued.where(
171
- '$or' => [
172
- {run_at: {'$exists' => false}},
173
- {run_at: {'$lte' => Time.now}}
174
- ]
150
+ def queued_now
151
+ queued.or(
152
+ {:run_at.exists => false},
153
+ {:run_at.lte => Time.now}
175
154
  )
176
155
  end
177
156
 
178
- # Returns the number of required arguments for this job
179
- def self.rocket_job_argument_count
180
- instance_method(:perform).arity
157
+ # DEPRECATED
158
+ def rocket_job
159
+ warn 'Replace calls to .rocket_job with calls to set class instance variables. For example: self.priority = 50'
160
+ yield(self)
181
161
  end
182
162
 
183
- # User definable properties in Dirmon Entry
184
- def self.rocket_job_properties
185
- @rocket_job_properties ||= (self == RocketJob::Job ? [] : superclass.rocket_job_properties)
163
+ # DEPRECATED
164
+ def public_rocket_job_properties(*args)
165
+ warn "Replace calls to .public_rocket_job_properties by adding `user_editable: true` option to the field declaration in #{name} for: #{args.inspect}"
166
+ self.user_editable_fields += args.collect(&:to_sym)
186
167
  end
187
-
188
- # Add to user definable properties in Dirmon Entry
189
- def self.public_rocket_job_properties(*properties)
190
- properties.each { |property| raise("Invalid public_rocket_job_property: #{property.inspect}") unless key?(property)}
191
- rocket_job_properties.concat(properties).uniq!
192
- end
193
-
194
- # User definable properties in Dirmon Entry
195
- public_rocket_job_properties :description, :priority, :log_level, :arguments
196
168
  end
197
169
 
198
170
  # Returns [true|false] whether to collect nil results from running this batch