rocketjob 6.1.0 → 6.2.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: fc1f3d316be0aa058cee5b22c116872a80ea5bdaf7d72db447ae13781ba6b370
4
- data.tar.gz: 87f56a455792e45ab2ad706f0c8bd625590df9942806bbd308c5145d07e94973
3
+ metadata.gz: d12a5469219af4b5781c67cf65670879f1fa349e42509431e5924015a52b4542
4
+ data.tar.gz: 745bbcfb5cc47a3413edf874b088b81382ccc185218aac3648adb1250e51b803
5
5
  SHA512:
6
- metadata.gz: f928a3afb886c39893ef5b5d2e13f71405c83df53c3b02826e474326c9171f87c84e595fc179a0e22cbc69d846f1da12eb268026fc06bcaf609920326159c6f4
7
- data.tar.gz: 3b90508c45e7a09739ae53e5bb66992d80251a5b5668eb568eeba30a8da8d109bbb162b2db66e93f82ce3deb4f6cc9425175d0f9c41adb351f6c3885768db3dc
6
+ metadata.gz: 012b3adb126e452c3ab4409d38d1fe02499cfc5049d5cc30074a1f607245e8da1327ad1a0a4b738ec290bcaf233cb7388132828d6f8f1684bdd70a1e17eb7c55
7
+ data.tar.gz: f8a1899798671265395f72d259afce338bea6e555755c33fdfa11928e10b14f29cc868570caa39f091f6863fa3c8809ab8874a6ba81b8b210c36c63e4454cf2b
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
 
@@ -466,6 +466,8 @@ module RocketJob
466
466
  output_collection.download(header_line: binary_header_line) { |record| io.write(record) }
467
467
  end
468
468
  else
469
+ # TODO: Add category to named tags to aid problem determination
470
+ # And RJ Download metric with duration
469
471
  IOStreams.new(stream || category.file_name).writer(:line, **args) do |io|
470
472
  output_collection.download(header_line: header_line) { |record| io << record }
471
473
  end
@@ -1,3 +1,4 @@
1
+ require "logger/severity"
1
2
  require "yaml"
2
3
  module RocketJob
3
4
  # Rocket Job Configuration
@@ -6,22 +6,26 @@ module Mongo
6
6
  include SemanticLogger::Loggable
7
7
  logger.name = "Mongo"
8
8
 
9
+ undef :started
9
10
  def started(event)
10
11
  @event_command = event.command
11
12
  end
12
13
 
14
+ undef :succeeded
13
15
  def succeeded(event)
14
16
  logger.debug(message: prefix(event),
15
17
  duration: (event.duration * 1000),
16
18
  payload: @event_command)
17
19
  end
18
20
 
21
+ undef :failed
19
22
  def failed(event)
20
23
  logger.debug(message: "#{prefix(event)} Failed: #{event.message}",
21
24
  duration: (event.duration * 1000),
22
25
  payload: @event_command)
23
26
  end
24
27
 
28
+ undef :prefix
25
29
  def prefix(event)
26
30
  "#{event.address} | #{event.database_name}.#{event.command_name}"
27
31
  end
@@ -82,7 +82,10 @@ module RocketJob
82
82
  end
83
83
 
84
84
  def apply_streams(path, streams)
85
- streams.each_pair { |stream, args| path.stream(stream.to_sym, args.nil? ? {} : decode_args(args)) }
85
+ streams.each_pair do |stream, args|
86
+ stream_args = args.nil? ? {} : decode_args(args)
87
+ path.stream(stream.to_sym, **stream_args)
88
+ end
86
89
  end
87
90
 
88
91
  def decode_args(args)
@@ -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
 
@@ -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
@@ -12,6 +12,7 @@ module RocketJob
12
12
  # Call the supplied block for every record returned
13
13
  record_count = 0
14
14
  each do |slice|
15
+ # TODO: Add slice_id to named tags to aid problem determination
15
16
  slice.each do |record|
16
17
  record_count += 1
17
18
  yield(record)
@@ -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.0".freeze
2
+ VERSION = "6.2.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.0
4
+ version: 6.2.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: 2021-11-04 00:00:00.000000000 Z
11
+ date: 2023-07-31 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.2.22
239
+ rubygems_version: 3.4.9
240
240
  signing_key:
241
241
  specification_version: 4
242
242
  summary: Ruby's missing batch processing system.