active_job_store 0.2.0 → 0.3.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: 913b4d81b0dfb938f013f907696dc04354a106818140d25003ae44ab4e4ed9f9
4
- data.tar.gz: 39874892b9ee2443311d54cfedf7589697959c5ccb4184d8d934d67960838c7d
3
+ metadata.gz: a9fd49a85e50473450a09a741acaf01d5e6565116cb6f945f314bd6e4dd74f6d
4
+ data.tar.gz: d5655ec674b4a86d99b267c8a851e2a8d1cd687e188c58c8a292bf5120cffc3b
5
5
  SHA512:
6
- metadata.gz: 18b9c5696a4b4092ae9ea5d6ae8ed74ed45aaef567804f53a7b59fee306038f6ce2e63f0832b9bdc6f6ad61dbb7d69b81239c5801fe39db2b163be50f0e468ad
7
- data.tar.gz: 0ad46829f63b6a6347812df19f0b0a3ef8b9e0c092ecf6f8f1743b08ddfeef9077735cdcb19690421222ca9557b2c6338b9e122d7e747f76a50d3357d62e3534
6
+ metadata.gz: f9e1a166e181d32afb0265ac062b954930b8d748af36b21e837d2ee6fe28a7d57edc2f9ad590339e49fefbc3256e6b43317d19ab4e9ff1de36e7f2aa67d0dac4
7
+ data.tar.gz: a407a4446dec032e4bf6f7b5f55536dadd703c0d1d1a75d61cdf37ace3388e09c836c520ffde6c0b31043867bd92c82ad04c57b54d7398ca126baa080715e0a5
data/README.md CHANGED
@@ -7,14 +7,11 @@
7
7
  Persist job execution information on a support model `ActiveJobStore::Record`.
8
8
 
9
9
  It can be useful to:
10
- - improve jobs logging capabilities;
11
- - query historical data about job executions;
12
- - extract job's statistical data;
13
- - track a job's state / set progress value / add custom data to the jobs.
10
+ - store the job's state / set progress value / add custom data to the jobs;
11
+ - query historical data about job executions / extract job's statistical data;
12
+ - improve jobs' logging capabilities.
14
13
 
15
- Support some customizations:
16
- - set custom data attributes (via `active_job_store_custom_data` accessor);
17
- - format the job result to store (overriding `active_job_store_format_result` method).
14
+ Please if you like it.
18
15
 
19
16
  ## Installation
20
17
 
@@ -24,6 +21,19 @@ Support some customizations:
24
21
  - Add to your job `include ActiveJobStore` (or to your `ApplicationJob` class if you prefer)
25
22
  - Access to the job executions data using the class method `job_executions` on your job (ex. `YourJob.job_executions`)
26
23
 
24
+ ## API
25
+
26
+ attr_accessor on the jobs:
27
+ - `active_job_store_custom_data`: to set / manipulate job's custom data
28
+
29
+ Instance methods on the jobs:
30
+ - `active_job_store_format_result(result) => result2`: to format / manipulate / serialize the job result
31
+ - `active_job_store_record => store record`: returns the store's record
32
+ - `save_job_custom_data(custom_data = nil)`: to persist custom data while the job is performing
33
+
34
+ Class methods on the jobs:
35
+ - `job_executions => relation`: query the list of job executions for the specific job class (returns an ActiveRecord Relation)
36
+
27
37
  ## Usage examples
28
38
 
29
39
  ```rb
@@ -48,18 +58,6 @@ SomeJob.job_executions.first
48
58
  # created_at: Wed, 09 Nov 2022 21:09:50.611900000 UTC +00:00>
49
59
  ```
50
60
 
51
- Extract some logs:
52
-
53
- ```rb
54
- puts ::ActiveJobStore::Record.order(id: :desc).pluck(:created_at, :job_class, :arguments, :state, :completed_at).map { _1.join(', ') }
55
- # 2022-11-09 21:20:57 UTC, SomeJob, 123, completed, 2022-11-09 21:20:58 UTC
56
- # 2022-11-09 21:18:26 UTC, AnotherJob, another test 2, completed, 2022-11-09 21:18:26 UTC
57
- # 2022-11-09 21:13:18 UTC, SomeJob, Some test 3, completed, 2022-11-09 21:13:19 UTC
58
- # 2022-11-09 21:12:18 UTC, SomeJob, Some test 2, error,
59
- # 2022-11-09 21:10:13 UTC, AnotherJob, another test, completed, 2022-11-09 21:10:13 UTC
60
- # 2022-11-09 21:09:50 UTC, SomeJob, Some test, completed, 2022-11-09 21:09:50 UTC
61
- ```
62
-
63
61
  Query jobs in a specific range of time:
64
62
 
65
63
  ```rb
@@ -77,7 +75,34 @@ SomeJob.job_executions.completed.map { |job| { id: job.id, execution_time: job.c
77
75
  # {:id=>1, :execution_time=>0.011442, :started_at=>Wed, 09 Nov 2022 21:09:50.611355000 UTC +00:00}]
78
76
  ```
79
77
 
80
- ## Customizations
78
+ Extract some logs:
79
+
80
+ ```rb
81
+ puts ::ActiveJobStore::Record.order(id: :desc).pluck(:created_at, :job_class, :arguments, :state, :completed_at).map { _1.join(', ') }
82
+ # 2022-11-09 21:20:57 UTC, SomeJob, 123, completed, 2022-11-09 21:20:58 UTC
83
+ # 2022-11-09 21:18:26 UTC, AnotherJob, another test 2, completed, 2022-11-09 21:18:26 UTC
84
+ # 2022-11-09 21:13:18 UTC, SomeJob, Some test 3, completed, 2022-11-09 21:13:19 UTC
85
+ # 2022-11-09 21:12:18 UTC, SomeJob, Some test 2, error,
86
+ # 2022-11-09 21:10:13 UTC, AnotherJob, another test, completed, 2022-11-09 21:10:13 UTC
87
+ # 2022-11-09 21:09:50 UTC, SomeJob, Some test, completed, 2022-11-09 21:09:50 UTC
88
+ ```
89
+
90
+ Query information from a job (even when it's performing):
91
+
92
+ ```rb
93
+ job = SomeJob.perform_later 123
94
+ job.active_job_store_record.slice(:job_id, :job_class, :arguments)
95
+ # => {"job_id"=>"b009f7c7-a264-4fb5-a1f8-68a8141f323b", "job_class"=>"SomeJob", "arguments"=>[123]}
96
+
97
+ job = AnotherJob.perform_later 456
98
+ job.active_job_store_record.custom_data
99
+ # => {"progress"=>0.5}
100
+ ### After a while:
101
+ job.active_job_store_record.reload.custom_data
102
+ # => {"progress"=>1.0}
103
+ ```
104
+
105
+ ## Features' details
81
106
 
82
107
  To store the custom data (ex. a progress value):
83
108
 
@@ -100,7 +125,7 @@ AnotherJob.perform_later(456)
100
125
  AnotherJob.job_executions.last.custom_data['progress'] # 1.0 (at the end)
101
126
  ```
102
127
 
103
- If you need to manipulate the custom data, there is the `active_job_store_custom_data` accessor:
128
+ To manipulate the custom data, there is the `active_job_store_custom_data` accessor:
104
129
 
105
130
  ```rb
106
131
  class AnotherJob < ApplicationJob
@@ -123,7 +148,7 @@ AnotherJob.job_executions.last.custom_data
123
148
  # => [{"time"=>"2022-11-09T21:20:57.580Z", "message"=>"SomeJob step 1"}, {"time"=>"2022-11-09T21:20:58.581Z", "message"=>"SomeJob step 2"}]
124
149
  ```
125
150
 
126
- If for any reason it's needed to process the result before storing it, just override `active_job_store_format_result`:
151
+ To process the result before storing it (ex. for serialization), override `active_job_store_format_result`:
127
152
 
128
153
  ```rb
129
154
  class AnotherJob < ApplicationJob
@@ -6,14 +6,36 @@ module ActiveJobStore
6
6
 
7
7
  attr_reader :record
8
8
 
9
+ def around_enqueue(job)
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
13
+ job_enqueued!
14
+ end
15
+
16
+ def around_perform(job)
17
+ prepare_record_on_perform(job)
18
+ job_started!
19
+ result = yield
20
+ formatted_result = job.active_job_store_format_result(result)
21
+ job_competed!(custom_data: job.active_job_store_custom_data, result: formatted_result)
22
+ rescue StandardError => e
23
+ job_failed!(exception: e, custom_data: job.active_job_store_custom_data)
24
+ raise
25
+ end
26
+
27
+ def update_job_custom_data(custom_data)
28
+ record.update!(custom_data: custom_data)
29
+ end
30
+
31
+ private
32
+
9
33
  def job_competed!(result:, custom_data:)
10
34
  record.update!(state: :completed, completed_at: Time.current, result: result, custom_data: custom_data)
11
35
  record
12
36
  end
13
37
 
14
38
  def job_enqueued!
15
- record.lock! # NOTE: needed to avoid update conflicts with perform when setting the state to enqueued
16
- yield
17
39
  record.update!(state: :enqueued, enqueued_at: Time.current)
18
40
  record
19
41
  end
@@ -44,12 +66,6 @@ module ActiveJobStore
44
66
  record
45
67
  end
46
68
 
47
- def update_job_custom_data(custom_data)
48
- record.update!(custom_data: custom_data)
49
- end
50
-
51
- private
52
-
53
69
  def record_reference(job)
54
70
  {
55
71
  job_id: job.job_id,
@@ -2,6 +2,6 @@
2
2
 
3
3
  # :nocov:
4
4
  module ActiveJobStore
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
7
7
  # :nocov:
@@ -4,47 +4,56 @@ require_relative 'active_job_store/engine'
4
4
  require_relative 'active_job_store/store'
5
5
 
6
6
  module ActiveJobStore
7
+ # Set / manipulate job's custom data
7
8
  attr_accessor :active_job_store_custom_data
8
9
 
9
- class << self
10
- def included(base)
11
- base.extend(ClassMethods)
12
-
13
- base.around_enqueue do |job, block|
14
- store.prepare_record_on_enqueue(job)
15
- store.job_enqueued! do
16
- block.call
17
- end
18
- end
19
-
20
- base.around_perform do |job, block|
21
- store.prepare_record_on_perform(job)
22
- store.job_started!
23
- result = block.call
24
- formatted_result = job.active_job_store_format_result(result)
25
- store.job_competed!(custom_data: active_job_store_custom_data, result: formatted_result)
26
- rescue StandardError => e
27
- store.job_failed!(exception: e, custom_data: active_job_store_custom_data)
28
- raise
29
- end
30
- end
31
- end
32
-
10
+ # Format / manipulate / serialize the job result
11
+ #
12
+ # @param result [any] Job's return value
13
+ #
14
+ # @return [any] Processed job's return value
33
15
  def active_job_store_format_result(result)
34
16
  result
35
17
  end
36
18
 
19
+ # Persist custom data while the job is performing
20
+ #
21
+ # @param custom_data [any] Attributes to serialize (it must be serializable in JSON)
37
22
  def save_job_custom_data(custom_data = nil)
38
23
  self.active_job_store_custom_data = custom_data if custom_data
39
24
  store.update_job_custom_data(active_job_store_custom_data)
40
25
  end
41
26
 
27
+ # Return the associated Active Job Store record
28
+ #
29
+ # @return [ActiveJobStore::Record] the corresponding record
30
+ def active_job_store_record
31
+ store.record
32
+ end
33
+
42
34
  module ClassMethods
35
+ # Query the list of job executions for the current job class
36
+ #
37
+ # @return [ActiveRecord Relation] query result
43
38
  def job_executions
44
39
  ::ActiveJobStore::Record.where(job_class: to_s)
45
40
  end
46
41
  end
47
42
 
43
+ class << self
44
+ def included(base)
45
+ base.extend(ClassMethods)
46
+
47
+ base.around_enqueue do |job, block|
48
+ store.around_enqueue(job) { block.call }
49
+ end
50
+
51
+ base.around_perform do |job, block|
52
+ store.around_perform(job) { block.call }
53
+ end
54
+ end
55
+ end
56
+
48
57
  private
49
58
 
50
59
  def store
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.2.0
4
+ version: 0.3.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: 2022-11-12 00:00:00.000000000 Z
11
+ date: 2022-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
27
41
  description: ActiveJob Store permits to store jobs state and custom data on a database
28
42
  email: mat@blocknot.es
29
43
  executables: []