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 +4 -4
- data/README.md +6 -6
- data/lib/rocket_job/batch/worker.rb +2 -2
- data/lib/rocket_job/category/base.rb +1 -1
- data/lib/rocket_job/category/input.rb +1 -1
- data/lib/rocket_job/config.rb +1 -0
- data/lib/rocket_job/jobs/copy_file_job.rb +1 -0
- data/lib/rocket_job/jobs/dirmon_job.rb +4 -0
- data/lib/rocket_job/jobs/upload_file_job.rb +8 -1
- data/lib/rocket_job/plugins/retry.rb +55 -5
- data/lib/rocket_job/rocket_job.rb +6 -3
- data/lib/rocket_job/sliced/input.rb +2 -2
- data/lib/rocket_job/sliced/slices.rb +1 -1
- data/lib/rocket_job/version.rb +1 -1
- data/lib/rocketjob.rb +1 -1
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a90e66a2d150e503e939735d7913b016e3cea3a9a43b6ae0751b101768f10c5c
|
4
|
+
data.tar.gz: bc0029bffda1dfa575984352c1284aaec8e93d8cb0f81789ae253740de3cc4d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
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
|
-
*
|
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.
|
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
|
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:
|
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:
|
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,
|
data/lib/rocket_job/config.rb
CHANGED
@@ -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
|
-
|
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
|
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 [
|
77
|
-
#
|
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
|
-
|
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:
|
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:
|
116
|
+
"$set" => {state: "queued"}
|
117
117
|
)
|
118
118
|
end
|
119
119
|
|
data/lib/rocket_job/version.rb
CHANGED
data/lib/rocketjob.rb
CHANGED
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.
|
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:
|
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.
|
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.
|
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.
|
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.
|
239
|
+
rubygems_version: 3.4.9
|
240
240
|
signing_key:
|
241
241
|
specification_version: 4
|
242
242
|
summary: Ruby's missing batch processing system.
|