active_job_store 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9fd49a85e50473450a09a741acaf01d5e6565116cb6f945f314bd6e4dd74f6d
4
- data.tar.gz: d5655ec674b4a86d99b267c8a851e2a8d1cd687e188c58c8a292bf5120cffc3b
3
+ metadata.gz: 0ef6d562f0f4a15a496ba433ec3c540e141936afb70c25c49d733989c5244662
4
+ data.tar.gz: bb6790c404ed7aecfc16a54838a01a25d366221e23898cb9bd52e73b2311de9e
5
5
  SHA512:
6
- metadata.gz: f9e1a166e181d32afb0265ac062b954930b8d748af36b21e837d2ee6fe28a7d57edc2f9ad590339e49fefbc3256e6b43317d19ab4e9ff1de36e7f2aa67d0dac4
7
- data.tar.gz: a407a4446dec032e4bf6f7b5f55536dadd703c0d1d1a75d61cdf37ace3388e09c836c520ffde6c0b31043867bd92c82ad04c57b54d7398ca126baa080715e0a5
6
+ metadata.gz: 5a88f03f2af219714771a7d9dcf320e72d99753f4327ce7f1c699ef8f0132bf62d124872e83ae2be589d88afba4f06aaecdc9506fc13cfe87b36e0777b46c4a3
7
+ data.tar.gz: b2544a3499f8a0d3a18b34fee58e171ef37cc3402890e1790746c75b97a6f22c236582185769738301aca986afa05e44fa27645a76a75f95480368dbee376aaf
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 when it's performing):
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' details
108
+ ## Features' examples
106
109
 
107
- To store the custom data (ex. a progress value):
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, there is the `active_job_store_custom_data` accessor:
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), override `active_job_store_format_result`:
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.
@@ -8,9 +8,11 @@ module ActiveJobStore
8
8
 
9
9
  def around_enqueue(job)
10
10
  prepare_record_on_enqueue(job)
11
- record.lock! # NOTE: needed to avoid update conflicts with perform when setting the state to enqueued
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
- record.update!(custom_data: custom_data)
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
- record.update!(state: :completed, completed_at: Time.current, result: result, custom_data: custom_data)
35
- record
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
- record.update!(state: :enqueued, enqueued_at: Time.current)
40
- record
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
- record.update!(state: :error, exception: exception.inspect, custom_data: custom_data)
45
- record
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
- record.update!(state: :started, started_at: Time.current)
50
- record
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
- @record = ::ActiveJobStore::Record.find_or_create_by!(record_reference(job)) do |record|
55
- record.arguments = job.arguments
56
- record.details = DETAILS_ATTRS.zip(DETAILS_ATTRS.map { job.send(_1) }).to_h
57
- record.state = :initialized
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
- @record = ::ActiveJobStore::Record.find_or_initialize_by(record_reference(job)) do |record|
63
- record.arguments = job.arguments
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  # :nocov:
4
4
  module ActiveJobStore
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  # :nocov:
@@ -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.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattia Roccoberton
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-15 00:00:00.000000000 Z
11
+ date: 2022-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -60,7 +60,7 @@ metadata:
60
60
  source_code_uri: https://github.com/blocknotes/active_job_store
61
61
  changelog_uri: https://github.com/blocknotes/active_job_store/blob/master/CHANGELOG.md
62
62
  rubygems_mfa_required: 'true'
63
- post_install_message:
63
+ post_install_message:
64
64
  rdoc_options: []
65
65
  require_paths:
66
66
  - lib
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
76
  version: '0'
77
77
  requirements: []
78
78
  rubygems_version: 3.1.6
79
- signing_key:
79
+ signing_key:
80
80
  specification_version: 4
81
81
  summary: Persist jobs information on DB
82
82
  test_files: []