active_job_store 0.3.0 → 0.4.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: 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: []