active_job_store 0.3.0 → 0.5.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/README.md +23 -5
- data/app/models/active_job_store/record.rb +4 -4
- data/lib/active_job_store/store.rb +49 -19
- data/lib/active_job_store/version.rb +1 -1
- data/lib/active_job_store.rb +7 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a53200d7e5f4f9654d3e8db62ef8a92014a78d264f43cece9486228a3ff03c9
|
4
|
+
data.tar.gz: b703fe5f1183d8c0718eb45e651580f02d41d0efae9eb81cc9e1a59c10e788a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 819a6339762b27117d43cf52075896611c5e83818018546a04c0727a03daad4f3a77b60c71030ef8218940ea1883223b4bf016b2a3e787f9b4fd810c2ded8f6b
|
7
|
+
data.tar.gz: a1bcf57d7b6f670dd90231abc21ed241a532a8ad7985b6e68b40b4b3c29001f8a23408f676ac4c0b45fb81e3102f33b8b2e3e7a9089add9410eb710465607cc0
|
data/README.md
CHANGED
@@ -11,6 +11,8 @@ It can be useful to:
|
|
11
11
|
- query historical data about job executions / extract job's statistical data;
|
12
12
|
- improve jobs' logging capabilities.
|
13
13
|
|
14
|
+
By default gem's internal errors are sent to stderr without compromising the job's perform.
|
15
|
+
|
14
16
|
Please ⭐ if you like it.
|
15
17
|
|
16
18
|
## Installation
|
@@ -28,6 +30,7 @@ attr_accessor on the jobs:
|
|
28
30
|
|
29
31
|
Instance methods on the jobs:
|
30
32
|
- `active_job_store_format_result(result) => result2`: to format / manipulate / serialize the job result
|
33
|
+
- `active_job_store_internal_error(context, exception)`: handler for internal errors
|
31
34
|
- `active_job_store_record => store record`: returns the store's record
|
32
35
|
- `save_job_custom_data(custom_data = nil)`: to persist custom data while the job is performing
|
33
36
|
|
@@ -87,7 +90,7 @@ puts ::ActiveJobStore::Record.order(id: :desc).pluck(:created_at, :job_class, :a
|
|
87
90
|
# 2022-11-09 21:09:50 UTC, SomeJob, Some test, completed, 2022-11-09 21:09:50 UTC
|
88
91
|
```
|
89
92
|
|
90
|
-
Query information from a job (even
|
93
|
+
Query information from a job (even while performing):
|
91
94
|
|
92
95
|
```rb
|
93
96
|
job = SomeJob.perform_later 123
|
@@ -102,9 +105,9 @@ job.active_job_store_record.reload.custom_data
|
|
102
105
|
# => {"progress"=>1.0}
|
103
106
|
```
|
104
107
|
|
105
|
-
## Features'
|
108
|
+
## Features' examples
|
106
109
|
|
107
|
-
To
|
110
|
+
To persist some custom data during the perform (ex. a progress value):
|
108
111
|
|
109
112
|
```rb
|
110
113
|
class AnotherJob < ApplicationJob
|
@@ -125,7 +128,7 @@ AnotherJob.perform_later(456)
|
|
125
128
|
AnotherJob.job_executions.last.custom_data['progress'] # 1.0 (at the end)
|
126
129
|
```
|
127
130
|
|
128
|
-
To manipulate the custom data
|
131
|
+
To manipulate the custom data persisted only at the end:
|
129
132
|
|
130
133
|
```rb
|
131
134
|
class AnotherJob < ApplicationJob
|
@@ -148,7 +151,7 @@ AnotherJob.job_executions.last.custom_data
|
|
148
151
|
# => [{"time"=>"2022-11-09T21:20:57.580Z", "message"=>"SomeJob step 1"}, {"time"=>"2022-11-09T21:20:58.581Z", "message"=>"SomeJob step 2"}]
|
149
152
|
```
|
150
153
|
|
151
|
-
To process the result before storing it (ex. for serialization)
|
154
|
+
To process the job's result before storing it (ex. for serialization):
|
152
155
|
|
153
156
|
```rb
|
154
157
|
class AnotherJob < ApplicationJob
|
@@ -169,6 +172,21 @@ AnotherJob.job_executions.last.result
|
|
169
172
|
# => 84
|
170
173
|
```
|
171
174
|
|
175
|
+
To raise an exception also when there is a gem's internal error:
|
176
|
+
|
177
|
+
```rb
|
178
|
+
class AnotherJob < ApplicationJob
|
179
|
+
include ActiveJobStore
|
180
|
+
|
181
|
+
# ...
|
182
|
+
|
183
|
+
def active_job_store_internal_error(context, exception)
|
184
|
+
raise exception
|
185
|
+
# Or simply monitor these errors using services like Sentry/Honeybadger/etc.
|
186
|
+
end
|
187
|
+
end
|
188
|
+
```
|
189
|
+
|
172
190
|
## Do you like it? Star it!
|
173
191
|
|
174
192
|
If you use this component just star it. A developer is more motivated to improve a project when there is some interest.
|
@@ -4,10 +4,10 @@ module ActiveJobStore
|
|
4
4
|
class Record < ApplicationRecord
|
5
5
|
self.table_name = 'active_job_store'
|
6
6
|
|
7
|
-
serialize :arguments, JSON
|
8
|
-
serialize :custom_data, JSON
|
9
|
-
serialize :details, JSON
|
10
|
-
serialize :result, JSON
|
7
|
+
serialize :arguments, coder: JSON
|
8
|
+
serialize :custom_data, coder: JSON
|
9
|
+
serialize :details, coder: JSON
|
10
|
+
serialize :result, coder: JSON
|
11
11
|
|
12
12
|
enum state: { initialized: 0, enqueued: 1, started: 2, completed: 3, error: 4 }
|
13
13
|
|
@@ -8,9 +8,11 @@ module ActiveJobStore
|
|
8
8
|
|
9
9
|
def around_enqueue(job)
|
10
10
|
prepare_record_on_enqueue(job)
|
11
|
-
|
12
|
-
yield
|
11
|
+
lock_record!
|
12
|
+
result = yield
|
13
13
|
job_enqueued!
|
14
|
+
job.active_job_store_internal_error('ActiveJobStore::Store around_enqueue', internal_error) if internal_error
|
15
|
+
result
|
14
16
|
end
|
15
17
|
|
16
18
|
def around_perform(job)
|
@@ -19,51 +21,71 @@ module ActiveJobStore
|
|
19
21
|
result = yield
|
20
22
|
formatted_result = job.active_job_store_format_result(result)
|
21
23
|
job_competed!(custom_data: job.active_job_store_custom_data, result: formatted_result)
|
24
|
+
job.active_job_store_internal_error('ActiveJobStore::Store around_perform', internal_error) if internal_error
|
25
|
+
result
|
22
26
|
rescue StandardError => e
|
23
27
|
job_failed!(exception: e, custom_data: job.active_job_store_custom_data)
|
24
28
|
raise
|
25
29
|
end
|
26
30
|
|
27
31
|
def update_job_custom_data(custom_data)
|
28
|
-
|
32
|
+
wrap_errors do
|
33
|
+
record.update!(custom_data: custom_data)
|
34
|
+
end
|
29
35
|
end
|
30
36
|
|
31
37
|
private
|
32
38
|
|
39
|
+
attr_accessor :internal_error
|
40
|
+
|
33
41
|
def job_competed!(result:, custom_data:)
|
34
|
-
|
35
|
-
|
42
|
+
wrap_errors do
|
43
|
+
record.update!(state: :completed, completed_at: Time.current, result: result, custom_data: custom_data)
|
44
|
+
end
|
36
45
|
end
|
37
46
|
|
38
47
|
def job_enqueued!
|
39
|
-
|
40
|
-
|
48
|
+
wrap_errors do
|
49
|
+
record.update!(state: :enqueued, enqueued_at: Time.current)
|
50
|
+
end
|
41
51
|
end
|
42
52
|
|
43
53
|
def job_failed!(exception:, custom_data:)
|
44
|
-
|
45
|
-
|
54
|
+
wrap_errors do
|
55
|
+
record.update!(state: :error, exception: exception.inspect, custom_data: custom_data)
|
56
|
+
end
|
46
57
|
end
|
47
58
|
|
48
59
|
def job_started!
|
49
|
-
|
50
|
-
|
60
|
+
wrap_errors do
|
61
|
+
record.update!(state: :started, started_at: Time.current)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def lock_record!
|
66
|
+
wrap_errors do
|
67
|
+
record.lock! # NOTE: needed to avoid update conflicts with perform when setting the state to enqueued
|
68
|
+
end
|
51
69
|
end
|
52
70
|
|
53
71
|
def prepare_record_on_enqueue(job)
|
54
|
-
|
55
|
-
record
|
56
|
-
|
57
|
-
|
72
|
+
wrap_errors do
|
73
|
+
@record = ::ActiveJobStore::Record.find_or_create_by!(record_reference(job)) do |record|
|
74
|
+
record.arguments = job.arguments
|
75
|
+
record.details = DETAILS_ATTRS.zip(DETAILS_ATTRS.map { job.send(_1) }).to_h
|
76
|
+
record.state = :initialized
|
77
|
+
end
|
58
78
|
end
|
59
79
|
end
|
60
80
|
|
61
81
|
def prepare_record_on_perform(job)
|
62
|
-
|
63
|
-
record
|
82
|
+
wrap_errors do
|
83
|
+
@record = ::ActiveJobStore::Record.find_or_initialize_by(record_reference(job)) do |record|
|
84
|
+
record.arguments = job.arguments
|
85
|
+
end
|
86
|
+
record.details = DETAILS_ATTRS.zip(DETAILS_ATTRS.map { job.send(_1) }).to_h
|
87
|
+
record
|
64
88
|
end
|
65
|
-
record.details = DETAILS_ATTRS.zip(DETAILS_ATTRS.map { job.send(_1) }).to_h
|
66
|
-
record
|
67
89
|
end
|
68
90
|
|
69
91
|
def record_reference(job)
|
@@ -72,5 +94,13 @@ module ActiveJobStore
|
|
72
94
|
job_class: job.class.to_s
|
73
95
|
}
|
74
96
|
end
|
97
|
+
|
98
|
+
def wrap_errors
|
99
|
+
return if internal_error
|
100
|
+
|
101
|
+
yield
|
102
|
+
rescue StandardError => e
|
103
|
+
self.internal_error = e
|
104
|
+
end
|
75
105
|
end
|
76
106
|
end
|
data/lib/active_job_store.rb
CHANGED
@@ -31,6 +31,13 @@ module ActiveJobStore
|
|
31
31
|
store.record
|
32
32
|
end
|
33
33
|
|
34
|
+
# Internal errors handler method
|
35
|
+
#
|
36
|
+
# @param exception [exception] The internal exception
|
37
|
+
def active_job_store_internal_error(context, exception)
|
38
|
+
warn("#{context}: #{exception}")
|
39
|
+
end
|
40
|
+
|
34
41
|
module ClassMethods
|
35
42
|
# Query the list of job executions for the current job class
|
36
43
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_job_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattia Roccoberton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -58,7 +58,7 @@ licenses:
|
|
58
58
|
metadata:
|
59
59
|
homepage_uri: https://github.com/blocknotes/active_job_store
|
60
60
|
source_code_uri: https://github.com/blocknotes/active_job_store
|
61
|
-
changelog_uri: https://github.com/blocknotes/active_job_store/blob/
|
61
|
+
changelog_uri: https://github.com/blocknotes/active_job_store/blob/main/CHANGELOG.md
|
62
62
|
rubygems_mfa_required: 'true'
|
63
63
|
post_install_message:
|
64
64
|
rdoc_options: []
|
@@ -68,14 +68,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
68
|
requirements:
|
69
69
|
- - ">="
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
version: 2.
|
71
|
+
version: 2.7.0
|
72
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
74
|
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '0'
|
77
77
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
78
|
+
rubygems_version: 3.4.19
|
79
79
|
signing_key:
|
80
80
|
specification_version: 4
|
81
81
|
summary: Persist jobs information on DB
|