belated 0.6.7 → 0.7.0
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.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -1
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +9 -2
- data/lib/active_job/queue_adapters/belated_adapter.rb +27 -0
- data/lib/belated/client.rb +4 -4
- data/lib/belated/job_wrapper.rb +26 -13
- data/lib/belated/queue.rb +2 -2
- data/lib/belated/testing.rb +2 -2
- data/lib/belated/version.rb +1 -1
- data/lib/belated.rb +19 -13
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 625adf33d85f1e94d4d7416db02a50e11fe66bfeb5fa265fa4de2c9b6f1c0750
|
|
4
|
+
data.tar.gz: 663fa5c0fcb7903b66324723a8cd19a771d596a88a396974d80060bf8c0bfd4a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e14413f88843ed9c80391987c5891f821ce0eb43e2759d5be034bb17a9cda78f4de7a67b97f44af933013dd4aef39e0d23d91df9ecfbbf3dbead38427a925450
|
|
7
|
+
data.tar.gz: aef2baada5a40a7da090e71e1c490d6f901e5178bd5be05001fb53c2863e9b03b86f9b997a53ced594d40aad8eb8700e25419b1378eba13b444b3b62f48d1b65
|
data/.github/workflows/main.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.7] - 2021-09-04
|
|
4
|
+
- ActiveJob support! Retries, exception rescuing should work as expected.
|
|
5
|
+
- Second Moderna jab took me out for a while... sorry for the long wait.
|
|
3
6
|
## [0.6.7] - 2021-08-25
|
|
4
7
|
|
|
5
8
|
- A bug fix for bad jobs bringing down client side.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -17,7 +17,6 @@ Can be used if you're on a normal instance such as EC2 or Digital Ocean drop. No
|
|
|
17
17
|
TODO LIST:
|
|
18
18
|
|
|
19
19
|
- Use GDBM for queue storage? That way could maybe get rid of YAML dumping and make things a bit safer. Not ordered though, so maybe keep a list of the jobs as YAML and update it sometimes? Just as backup. Or RocksDB? Would need to be configurable if you don't have something installed.
|
|
20
|
-
- Maybe support ActiveJob?
|
|
21
20
|
- Have a web UI.
|
|
22
21
|
- Have a job history
|
|
23
22
|
- Do some performance testing.
|
|
@@ -48,7 +47,15 @@ Start up Belated!
|
|
|
48
47
|
|
|
49
48
|
$ belated
|
|
50
49
|
|
|
51
|
-
|
|
50
|
+
If you're using Rails, just set Belated to be the ActiveJob adapter like below:
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
config.active_job.adapter = :belated
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
And you're good to go!
|
|
57
|
+
|
|
58
|
+
If not, in your non-ActiveJob using program, connect to Belated and give it a job to do.
|
|
52
59
|
Sample below:
|
|
53
60
|
|
|
54
61
|
```ruby
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'belated'
|
|
4
|
+
|
|
5
|
+
module ActiveJob # :nodoc:
|
|
6
|
+
module QueueAdapters # :nodoc:
|
|
7
|
+
# The adapter in charge of handling ActiveJob integration.
|
|
8
|
+
# WIP
|
|
9
|
+
class BelatedAdapter
|
|
10
|
+
def instance
|
|
11
|
+
@instance ||= Belated::Client.instance
|
|
12
|
+
rescue StandardError
|
|
13
|
+
@instance = Belated::Client.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def enqueue(job) # :nodoc:
|
|
17
|
+
Rails.logger.info "Belated got job #{job}"
|
|
18
|
+
instance.perform(job, active_job: true)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def enqueue_at(job, timestamp) # :nodoc:
|
|
22
|
+
Rails.logger.info "Belated got job #{job} to be performed at #{Time.at(timestamp)}"
|
|
23
|
+
instance.perform_belated(job, at: timestamp, active_job: true)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/belated/client.rb
CHANGED
|
@@ -74,11 +74,11 @@ class Belated
|
|
|
74
74
|
# @param at [Date] - The time at which the job should be executed.
|
|
75
75
|
# @param max_retries [Integer] - Times the job should be retried if it fails.
|
|
76
76
|
# @return [JobWrapper] - The job wrapper for the queue.
|
|
77
|
-
def perform(job, at: nil, max_retries: 5)
|
|
77
|
+
def perform(job, at: nil, max_retries: 5, active_job: false)
|
|
78
78
|
start unless started?
|
|
79
79
|
return unless proper_job?(job)
|
|
80
80
|
|
|
81
|
-
job_wrapper = wrap_job(job, at: at, max_retries: max_retries)
|
|
81
|
+
job_wrapper = wrap_job(job, at: at.to_f, max_retries: max_retries, active_job: active_job)
|
|
82
82
|
bank.push(job_wrapper)
|
|
83
83
|
@mutex.synchronize do
|
|
84
84
|
proc_table[job_wrapper.object_id] = job_wrapper if job_wrapper.proc_klass
|
|
@@ -98,10 +98,10 @@ class Belated
|
|
|
98
98
|
false
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
def wrap_job(job, at:, max_retries:)
|
|
101
|
+
def wrap_job(job, at:, max_retries:, active_job:)
|
|
102
102
|
return job if job.is_a?(JobWrapper)
|
|
103
103
|
|
|
104
|
-
JobWrapper.new(job: job, at: at, max_retries: max_retries)
|
|
104
|
+
JobWrapper.new(job: job, at: at, max_retries: max_retries, active_job: active_job)
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
def drb_connected?
|
data/lib/belated/job_wrapper.rb
CHANGED
|
@@ -13,16 +13,17 @@ class Belated
|
|
|
13
13
|
class JobWrapper
|
|
14
14
|
include Comparable
|
|
15
15
|
include Logging
|
|
16
|
-
attr_accessor :retries, :max_retries, :id, :job, :at, :completed, :proc_klass
|
|
16
|
+
attr_accessor :retries, :max_retries, :id, :job, :at, :completed, :proc_klass, :error, :active_job
|
|
17
17
|
|
|
18
|
-
def initialize(job:, max_retries: 5, at: nil)
|
|
18
|
+
def initialize(job:, max_retries: 5, at: nil, active_job: false)
|
|
19
19
|
self.retries = 0
|
|
20
20
|
self.max_retries = max_retries
|
|
21
|
-
self.id = SecureRandom.uuid
|
|
21
|
+
self.id = job.respond_to?(:job_id) ? job.job_id : SecureRandom.uuid
|
|
22
22
|
self.job = job
|
|
23
23
|
self.at = at
|
|
24
24
|
self.completed = false
|
|
25
25
|
self.proc_klass = job.instance_of?(Proc)
|
|
26
|
+
self.active_job = active_job
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
def <=>(other)
|
|
@@ -31,11 +32,7 @@ class Belated
|
|
|
31
32
|
|
|
32
33
|
# rubocop:disable Lint/RescueException
|
|
33
34
|
def perform
|
|
34
|
-
resp =
|
|
35
|
-
job.call
|
|
36
|
-
else
|
|
37
|
-
job.perform
|
|
38
|
-
end
|
|
35
|
+
resp = execute
|
|
39
36
|
self.completed = true
|
|
40
37
|
resp
|
|
41
38
|
rescue Exception => e
|
|
@@ -43,17 +40,33 @@ class Belated
|
|
|
43
40
|
when Interrupt, SignalException
|
|
44
41
|
raise e
|
|
45
42
|
else
|
|
46
|
-
retry_job
|
|
47
|
-
"Error while executing job, #{e.inspect}. Retry #{retries} of #{max_retries}"
|
|
43
|
+
retry_job(e)
|
|
44
|
+
"Error while executing job #{job.inspect}, #{e.inspect}. Retry #{retries} of #{max_retries}"
|
|
48
45
|
end
|
|
49
46
|
end
|
|
47
|
+
|
|
50
48
|
# rubocop:enable Lint/RescueException
|
|
49
|
+
def execute
|
|
50
|
+
if active_job
|
|
51
|
+
ActiveJob::Base.execute job.serialize
|
|
52
|
+
elsif job.respond_to?(:call)
|
|
53
|
+
job.call
|
|
54
|
+
elsif job.respond_to?(:arguments)
|
|
55
|
+
job.perform(*job.arguments)
|
|
56
|
+
else
|
|
57
|
+
job.perform
|
|
58
|
+
end
|
|
59
|
+
end
|
|
51
60
|
|
|
52
|
-
def retry_job
|
|
61
|
+
def retry_job(error)
|
|
53
62
|
self.retries += 1
|
|
54
|
-
|
|
63
|
+
if retries > max_retries
|
|
64
|
+
self.error = error
|
|
65
|
+
return
|
|
66
|
+
end
|
|
55
67
|
|
|
56
|
-
|
|
68
|
+
seconds_to_retry = $TESTING ? 0.05 : retries.next**4
|
|
69
|
+
self.at = (Time.now + seconds_to_retry).to_f
|
|
57
70
|
log "Job #{id} failed, retrying at #{at}"
|
|
58
71
|
Belated.job_list.push(self)
|
|
59
72
|
end
|
data/lib/belated/queue.rb
CHANGED
|
@@ -25,7 +25,7 @@ class Belated
|
|
|
25
25
|
|
|
26
26
|
def push(job)
|
|
27
27
|
if job.is_a?(Symbol) || job.at.nil? ||
|
|
28
|
-
job.at <= Time.now.
|
|
28
|
+
job.at <= Time.now.to_f
|
|
29
29
|
@queue.push(job)
|
|
30
30
|
else
|
|
31
31
|
@mutex.synchronize do
|
|
@@ -57,7 +57,7 @@ class Belated
|
|
|
57
57
|
|
|
58
58
|
jobs = YAML.load(File.binread(FILE_NAME))
|
|
59
59
|
jobs.each do |job|
|
|
60
|
-
if job.at && job.at > Time.now.
|
|
60
|
+
if job.at && job.at > Time.now.to_f
|
|
61
61
|
future_jobs.push(job)
|
|
62
62
|
else
|
|
63
63
|
@queue.push(job)
|
data/lib/belated/testing.rb
CHANGED
|
@@ -22,7 +22,7 @@ class Belated
|
|
|
22
22
|
# A client that can perform jobs inline
|
|
23
23
|
class Client
|
|
24
24
|
alias old_perform perform
|
|
25
|
-
def perform(job, at: nil, max_retries: 5)
|
|
25
|
+
def perform(job, at: nil, max_retries: 5, active_job: false)
|
|
26
26
|
if Belated::Testing.inline?
|
|
27
27
|
if job.respond_to?(:call)
|
|
28
28
|
job.call
|
|
@@ -30,7 +30,7 @@ class Belated
|
|
|
30
30
|
job.perform
|
|
31
31
|
end
|
|
32
32
|
else
|
|
33
|
-
old_perform(job, at: at, max_retries: max_retries)
|
|
33
|
+
old_perform(job, at: at, max_retries: max_retries, active_job: active_job)
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
end
|
data/lib/belated/version.rb
CHANGED
data/lib/belated.rb
CHANGED
|
@@ -65,6 +65,7 @@ class Belated
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def trap_signals
|
|
68
|
+
pp 'trap'
|
|
68
69
|
%w[INT TERM].each do |signal|
|
|
69
70
|
Signal.trap(signal) do
|
|
70
71
|
@worker_list.length.times do
|
|
@@ -101,7 +102,7 @@ class Belated
|
|
|
101
102
|
sleep Belated.heartbeat
|
|
102
103
|
next
|
|
103
104
|
end
|
|
104
|
-
if job.at <= Time.now
|
|
105
|
+
if job.at <= Time.now.to_f
|
|
105
106
|
log "Deleting #{@@queue.future_jobs.delete(job)} from future jobs"
|
|
106
107
|
@@queue.push(job)
|
|
107
108
|
end
|
|
@@ -156,19 +157,25 @@ class Belated
|
|
|
156
157
|
}
|
|
157
158
|
end
|
|
158
159
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
class << self
|
|
161
|
+
def find(job_id)
|
|
162
|
+
@@queue.future_jobs.find { |job| job.id == job_id }
|
|
162
163
|
end
|
|
163
|
-
clear_queue!
|
|
164
|
-
end
|
|
165
164
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
165
|
+
def kill_and_clear_queue!
|
|
166
|
+
@worker_list&.each do |worker|
|
|
167
|
+
Thread.kill(worker)
|
|
168
|
+
end
|
|
169
|
+
clear_queue!
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def clear_queue!
|
|
173
|
+
@@queue.clear
|
|
174
|
+
end
|
|
169
175
|
|
|
170
|
-
|
|
171
|
-
|
|
176
|
+
def fetch_job
|
|
177
|
+
@@queue.pop
|
|
178
|
+
end
|
|
172
179
|
end
|
|
173
180
|
|
|
174
181
|
def job_list
|
|
@@ -179,5 +186,4 @@ class Belated
|
|
|
179
186
|
@@queue
|
|
180
187
|
end
|
|
181
188
|
end
|
|
182
|
-
|
|
183
|
-
require 'belated/rails' if defined?(::Rails::Engine)
|
|
189
|
+
require 'active_job/queue_adapters/belated_adapter' if defined?(::Rails)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: belated
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sampo Kuokkanen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-09-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: drb
|
|
@@ -106,6 +106,7 @@ files:
|
|
|
106
106
|
- bin/bundle
|
|
107
107
|
- bin/console
|
|
108
108
|
- bin/setup
|
|
109
|
+
- lib/active_job/queue_adapters/belated_adapter.rb
|
|
109
110
|
- lib/belated.rb
|
|
110
111
|
- lib/belated/client.rb
|
|
111
112
|
- lib/belated/exceptions.rb
|