rocketjob 6.1.1 → 6.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca9a7af0f4448efdb418e738f95bc5f885d2399bdfd50ce3d0533c6928f3f78f
4
- data.tar.gz: e0f1bc3fb3c60989f22ff4d75c1ed86c8f7a998bdc5bc02f0f8616dd9631029e
3
+ metadata.gz: a90e66a2d150e503e939735d7913b016e3cea3a9a43b6ae0751b101768f10c5c
4
+ data.tar.gz: bc0029bffda1dfa575984352c1284aaec8e93d8cb0f81789ae253740de3cc4d9
5
5
  SHA512:
6
- metadata.gz: 79e914a57bbdae9026cbe783d8a1743e538bb2b1ffebacb527561ef961174eaa24693e850e0b72ee9ae113611db96fe1e0e2edb85d6395cbc057b7fc17bf11e9
7
- data.tar.gz: f6a8ba0b5060f54072a68fc396e43a3b9ba1c53b58e6b282006e111792e612d301b737279a344be252fc659724b70e12cff5400f49eb47316d38eda0571788f3
6
+ metadata.gz: 4350c6360df190ccb0c251944cf4bf5bc20de512779b5f6e0107571c049f7adc2e589de63ba350d1c179505e3af2ff5610220edbfc9e43f4c0abff4943448ee6
7
+ data.tar.gz: 9924be8c32392448e6285e9f2a94c1da26abd5b29a2d2aa7d60ff0cee8e34c61cedd6c69cc109894dfeaa9e5ce5dcfea0b2084bacce0493b2e44c5c6f2c813fc
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Rocket Job
2
- [![Gem Version](https://img.shields.io/gem/v/rocketjob.svg)](https://rubygems.org/gems/rocketjob) [![Downloads](https://img.shields.io/gem/dt/rocketjob.svg)](https://rubygems.org/gems/rocketjob) [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/badge/status-Production%20Ready-blue.svg) [![Support](https://img.shields.io/badge/IRC%20(gitter)-Support-brightgreen.svg)](https://gitter.im/rocketjob/support)
2
+ [![Gem Version](https://img.shields.io/gem/v/rocketjob.svg)](https://rubygems.org/gems/rocketjob) [![Downloads](https://img.shields.io/gem/dt/rocketjob.svg)](https://rubygems.org/gems/rocketjob) [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/badge/status-Production%20Ready-blue.svg)
3
3
 
4
4
  Ruby's missing batch system
5
5
 
@@ -14,7 +14,7 @@ Checkout https://rocketjob.io/
14
14
 
15
15
  ## Support
16
16
 
17
- * Questions? Join the chat room on Gitter for [rocketjob support](https://gitter.im/rocketjob/support)
17
+ * Ask questions in [Rocket Job Discussions](https://github.com/reidmorrison/rocketjob/discussions)
18
18
  * [Report bugs](https://github.com/rocketjob/rocketjob/issues)
19
19
 
20
20
  ## Rocket Job v6
@@ -106,8 +106,8 @@ These fields have been removed from the job itself:
106
106
  ~~~ruby
107
107
  class MyJob < RocketJob::Job
108
108
  include RocketJob::Batch
109
-
110
- self.slice_sice = 1_000
109
+
110
+ self.slice_size = 1_000
111
111
  self.encrypt = true
112
112
  self.compress = true
113
113
  end
@@ -123,8 +123,8 @@ If the serializer is set to `encrypt` then it is automatically compressed.
123
123
  ~~~ruby
124
124
  class MyJob < RocketJob::Job
125
125
  include RocketJob::Batch
126
-
127
- input_category slice_sice: 1_000, serializer: :encrypt
126
+
127
+ input_category slice_size: 1_000, serializer: :encrypt
128
128
  end
129
129
  ~~~
130
130
 
@@ -226,7 +226,7 @@ module RocketJob
226
226
  result = self.class.with(write: {w: 1}) do |query|
227
227
  query.
228
228
  where(id: id, state: :running, sub_state: :processing).
229
- update("$set" => {sub_state: :after, worker_name: worker_name})
229
+ update("$set" => {sub_state: "after", worker_name: worker_name})
230
230
  end
231
231
 
232
232
  # Reload to pull in any counters or other data that was modified.
@@ -251,7 +251,7 @@ module RocketJob
251
251
  result = self.class.with(write: {w: 1}) do |query|
252
252
  query.
253
253
  where(id: id, state: :running, sub_state: :processing).
254
- update({"$set" => {state: :failed, worker_name: worker_name}})
254
+ update({"$set" => {state: "failed", worker_name: worker_name}})
255
255
  end
256
256
  fail_job = false unless result.modified_count.positive?
257
257
  end
@@ -61,7 +61,7 @@ module RocketJob
61
61
  @tabular ||= IOStreams::Tabular.new(
62
62
  columns: columns,
63
63
  format: format == :auto ? nil : format,
64
- format_options: format_options&.deep_symbolize_keys,
64
+ format_options: format_options&.to_h&.deep_symbolize_keys,
65
65
  file_name: file_name
66
66
  )
67
67
  end
@@ -99,7 +99,7 @@ module RocketJob
99
99
  @tabular ||= IOStreams::Tabular.new(
100
100
  columns: columns,
101
101
  format: format == :auto ? nil : format,
102
- format_options: format_options&.deep_symbolize_keys,
102
+ format_options: format_options&.to_h&.deep_symbolize_keys,
103
103
  file_name: file_name,
104
104
  allowed_columns: allowed_columns,
105
105
  required_columns: required_columns,
@@ -1,3 +1,4 @@
1
+ require "logger/severity"
1
2
  require "yaml"
2
3
  module RocketJob
3
4
  # Rocket Job Configuration
@@ -26,6 +26,7 @@ module RocketJob
26
26
  self.destroy_on_complete = false
27
27
  # Number of times to automatically retry the copy. Set to `0` for no retry attempts.
28
28
  self.retry_limit = 10
29
+ self.prioriy = 30
29
30
 
30
31
  # File names in IOStreams URL format.
31
32
  field :source_url, type: String, user_editable: true
@@ -42,6 +42,10 @@ module RocketJob
42
42
  self.description = "Directory Monitor"
43
43
  self.priority = 30
44
44
 
45
+ # Prevent multiple dirmon jobs from running at the same time by only
46
+ # creating the next instance when this one finishes.
47
+ self.cron_after_start = false
48
+
45
49
  # Hash[file_name, size]
46
50
  field :previous_file_names, type: Hash, default: {}, copy_on_restart: true
47
51
 
@@ -59,7 +59,14 @@ module RocketJob
59
59
  if job.respond_to?(:upload)
60
60
  # Return the database connection for this thread back to the connection pool
61
61
  # in case the upload takes a long time and the database connection expires.
62
- ActiveRecord::Base.clear_active_connections! if defined?(ActiveRecord::Base)
62
+ if defined?(ActiveRecord::Base)
63
+ if ActiveRecord::Base.respond_to?(:connection_handler)
64
+ # Rails 7
65
+ ActiveRecord::Base.connection_handler.clear_active_connections!
66
+ else
67
+ ActiveRecord::Base.connection_pool.release_connection
68
+ end
69
+ end
63
70
 
64
71
  if original_file_name
65
72
  job.upload(upload_file_name, file_name: original_file_name)
@@ -26,14 +26,51 @@ module RocketJob
26
26
  # # Disable retries for this job instance.
27
27
  # MyCronJob.create!(retry_limit: 0)
28
28
  #
29
+ # Below is a table of the delay for each retry attempt, as well as the _total_ duration spent retrying a job for
30
+ # the specified number of retries, excluding actual processing time.
31
+ #
32
+ # |---------|------------|----------------|
33
+ # | Attempt | Delay | Total Duration |
34
+ # |---------|------------|----------------|
35
+ # | 01 | 6.000s | 6.000s |
36
+ # | 02 | 21.000s | 27.000s |
37
+ # | 03 | 1m 26s | 1m 53s |
38
+ # | 04 | 4m 21s | 6m 14s |
39
+ # | 05 | 10m 30s | 16m 44s |
40
+ # | 06 | 21m 41s | 38m 25s |
41
+ # | 07 | 40m 6s | 20h 18m |
42
+ # | 08 | 20h 8m | 21h 26m |
43
+ # | 09 | 20h 49m | 23h 16m |
44
+ # | 10 | 21h 46m | 2h 3m |
45
+ # | 11 | 23h 4m | 6h 7m |
46
+ # | 12 | 0h 45m | 11h 52m |
47
+ # | 13 | 2h 56m | 1d 19h 48m |
48
+ # | 14 | 5h 40m | 1d 6h 29m |
49
+ # | 15 | 9h 3m | 2d 20h 33m |
50
+ # | 16 | 13h 12m | 2d 14h 45m |
51
+ # | 17 | 18h 12m | 3d 13h 57m |
52
+ # | 18 | 1d 0h 9m | 5d 19h 7m |
53
+ # | 19 | 1d 7h 12m | 6d 7h 19m |
54
+ # | 20 | 1d 15h 26m | 8d 3h 46m |
55
+ # | 21 | 2d 1h 1m | 10d 9h 47m |
56
+ # | 22 | 2d 12h 4m | 13d 2h 51m |
57
+ # | 23 | 3d 0h 44m | 16d 8h 35m |
58
+ # | 24 | 3d 15h 9m | 20d 4h 45m |
59
+ # | 25 | 4d 7h 30m | 24d 17h 16 |
60
+ # | 26 | 5d 1h 56m | 30d 0h 12m |
61
+ # | 27 | 6d 22h 37m | 36d 3h 49m |
62
+ # | 28 | 7d 21h 44m | 43d 6h 34m |
63
+ # | 29 | 8d 23h 28m | 51d 11h 2m |
64
+ # | 30 | 9d 4h 0m | 61d 20h 2m |
65
+ # |---------|------------|----------------|
29
66
  module Retry
30
67
  extend ActiveSupport::Concern
31
68
 
32
69
  included do
33
70
  after_fail :rocket_job_retry
34
71
 
35
- # Maximum number of times to retry this job
36
- # 25 is approximately 3 weeks of retries
72
+ # Maximum number of times to retry this job.
73
+ # The default of 25 is almost 25 days of retries.
37
74
  field :retry_limit, type: Integer, default: 25, class_attribute: true, user_editable: true, copy_on_restart: true
38
75
 
39
76
  # List of times when this job failed
@@ -73,10 +110,23 @@ module RocketJob
73
110
  self.worker_name = nil
74
111
  end
75
112
 
76
- # Returns [Time] when to retry this job at
77
- # Same basic formula as Delayed Job
113
+ # Returns [Integer] the number of seconds after which to retry this failed job.
114
+ # Uses an exponential back-off algorithm to prevent overloading the failed resource.
115
+ #
116
+ # For example, to see the durations for the first 25 retries:
117
+ # count = 25
118
+ # intervals = (1..count).map { |attempt| attempt**4 + 5 }
119
+ #
120
+ # Display the above intervals as human readable durations:
121
+ # intervals.map { |seconds| RocketJob.seconds_as_duration(seconds) }
122
+ #
123
+ # Then sum the total duration in seconds:
124
+ # RocketJob.seconds_as_duration(intervals.sum)
125
+ #
126
+ # Or, to see the total durations based on the number of retries:
127
+ # (0..count).map{|i| "#{i+1} ==> #{RocketJob.seconds_as_duration(intervals[0..i].sum)}"}
78
128
  def rocket_job_retry_seconds_to_delay
79
- (rocket_job_failure_count**4) + 15 + (rand(30) * (rocket_job_failure_count + 1))
129
+ rocket_job_failure_count**4 + 5
80
130
  end
81
131
  end
82
132
  end
@@ -28,11 +28,11 @@ module RocketJob
28
28
  return nil unless seconds
29
29
 
30
30
  if seconds >= 86_400.0 # 1 day
31
- "#{(seconds / 86_400).to_i}d #{Time.at(seconds).strftime('%-Hh %-Mm')}"
31
+ "#{(seconds / 86_400).to_i}d #{Time.at(seconds).utc.strftime('%-Hh %-Mm')}"
32
32
  elsif seconds >= 3600.0 # 1 hour
33
- Time.at(seconds).strftime("%-Hh %-Mm")
33
+ Time.at(seconds).utc.strftime("%-Hh %-Mm")
34
34
  elsif seconds >= 60.0 # 1 minute
35
- Time.at(seconds).strftime("%-Mm %-Ss")
35
+ Time.at(seconds).utc.strftime("%-Mm %-Ss")
36
36
  elsif seconds >= 1.0 # 1 second
37
37
  format("%.3fs", seconds)
38
38
  else
@@ -58,3 +58,6 @@ module RocketJob
58
58
  @rails = true
59
59
  end
60
60
  end
61
+
62
+ # Slice is a reserved word in Rails 7, but already being used in RocketJob long before that.
63
+ Mongoid.destructive_fields.delete(:slice) if Mongoid.respond_to?(:destructive_fields)
@@ -105,7 +105,7 @@ module RocketJob
105
105
  def requeue_failed
106
106
  failed.update_all(
107
107
  "$unset" => {worker_name: nil, started_at: nil},
108
- "$set" => {state: :queued}
108
+ "$set" => {state: "queued"}
109
109
  )
110
110
  end
111
111
 
@@ -113,7 +113,7 @@ module RocketJob
113
113
  def requeue_running(worker_name)
114
114
  running.where(worker_name: /\A#{worker_name}/).update_all(
115
115
  "$unset" => {worker_name: nil, started_at: nil},
116
- "$set" => {state: :queued}
116
+ "$set" => {state: "queued"}
117
117
  )
118
118
  end
119
119
 
@@ -92,7 +92,7 @@ module RocketJob
92
92
 
93
93
  def insert_many(slices)
94
94
  documents = slices.collect(&:as_document)
95
- all.collection.insert_many(documents)
95
+ all.collection.insert_many(documents) if documents.present?
96
96
  end
97
97
 
98
98
  # Append to an existing slice if already present
@@ -1,3 +1,3 @@
1
1
  module RocketJob
2
- VERSION = "6.1.1".freeze
2
+ VERSION = "6.3.0".freeze
3
3
  end
data/lib/rocketjob.rb CHANGED
@@ -1,6 +1,6 @@
1
- require "iostreams"
2
1
  require "semantic_logger"
3
2
  require "symmetric-encryption"
3
+ require "iostreams"
4
4
  require "mongoid"
5
5
  require "rocket_job/extensions/mongo/logging"
6
6
  require "rocket_job/extensions/iostreams/path"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rocketjob
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.1
4
+ version: 6.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-27 00:00:00.000000000 Z
11
+ date: 2023-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aasm
@@ -28,58 +28,58 @@ dependencies:
28
28
  name: concurrent-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: fugit
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.4'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: iostreams
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.9'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.9'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: mongoid
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '7.1'
75
+ version: '7.5'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '7.1'
82
+ version: '7.5'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: semantic_logger
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -98,14 +98,14 @@ dependencies:
98
98
  name: symmetric-encryption
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '4.3'
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: '4.3'
111
111
  description:
@@ -229,14 +229,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
229
229
  requirements:
230
230
  - - ">="
231
231
  - !ruby/object:Gem::Version
232
- version: '2.5'
232
+ version: '2.7'
233
233
  required_rubygems_version: !ruby/object:Gem::Requirement
234
234
  requirements:
235
235
  - - ">="
236
236
  - !ruby/object:Gem::Version
237
237
  version: '0'
238
238
  requirements: []
239
- rubygems_version: 3.3.7
239
+ rubygems_version: 3.4.9
240
240
  signing_key:
241
241
  specification_version: 4
242
242
  summary: Ruby's missing batch processing system.