background_worker 0.8.1 → 0.9.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: 061e6c0338c031523b85a90f084aaf996c00cbe9e668428931a98ae3b5a12f36
4
- data.tar.gz: 36304e141265bc21d2d756d2af7aab6645fbfa9596d5ab5bfe2c115132f685a8
3
+ metadata.gz: 6354bdc8bc64824ab09d3b2666d1bfcab6c6b02f7b5c5e2cab58902e840eaf7b
4
+ data.tar.gz: 49f0ffc416005df1da66eb112852dc0eb8246978f3e477fdefdccda9eef3e0f5
5
5
  SHA512:
6
- metadata.gz: f799063ea369646eea2956427aa7bc0cd551229649e9e3cb1b324a8bd1edec162c7d0852dbf0c7ce724d0332c702208097c5a975827d050742c0df11e5e3709a
7
- data.tar.gz: 6d4487e464251517e318fe59be864d87da48f324aabce3b6d8964971f55fa1a4a3b5dc7f66913fe6ee5654614a72d6fb978887a84829e0afe656313b6d693ca6
6
+ metadata.gz: 306de71726dc7d080ce55e51617e926d84cc99b7abec077381ea820e4e2434c63c023e3ed97ac60f0bd15bf230af9533fb0b411544436e9ac4099bf7e2057d15
7
+ data.tar.gz: f5d75d708b036479a944632f6c38a8be872125ce6c7b8459b72f3f9266a9a2c2cd027aad93a1d59d8ff82d665dec05ef9101bf61b32cc83ab10bcd70a3e214be
data/CHANGELOG.md CHANGED
@@ -1,7 +1,17 @@
1
1
  # Change Log
2
+
2
3
  All notable changes to this project will be documented in this file.
3
4
  This project adheres to [Semantic Versioning](http://semver.org/).
4
- This changelog adheres to [Keep a CHANGELOG](http://keepachangelog.com/).
5
+ This changelog adheres to [Keep a CHANGELOG](http://keepachangelog.com/).
6
+
7
+ ## 0.9.0
8
+
9
+ - [PLAT-749] Rename `uid` as `job_id` and make it a base property of job.
10
+ - [PLAT-759] Add callbacks
11
+ - [PLAT-761] Extract logging concern
12
+ - [PLAT-760] Extract status concern
13
+ - [PLAT-762] Perform now and later will return job object
14
+ - [PLAT-780] Fix callbacks
5
15
 
6
16
  ## 0.8.1
7
17
 
@@ -32,14 +42,20 @@ This changelog adheres to [Keep a CHANGELOG](http://keepachangelog.com/).
32
42
  - [TT-6292] Support Rails 5.2 built-in redis cache, remove legacy supports
33
43
 
34
44
  ## 0.2.1
45
+
35
46
  ### Fixed
47
+
36
48
  - [RU-123] Worker disconnecting within transactions in rails 4+
37
49
 
38
50
  ## 0.2.0
51
+
39
52
  ### Added
53
+
40
54
  - [RU-79] Release connections after execution for Rails 4
41
55
 
42
56
  ## 0.1.0
57
+
43
58
  ### Added
59
+
44
60
  - [TT-1392] Changelog file
45
61
  - [TT-2141] Only verify connections for Rails 3
@@ -1,91 +1,57 @@
1
- require 'background_worker/uid'
1
+ require "active_support/callbacks"
2
2
  require 'background_worker/persistent_state'
3
3
  require 'background_worker/worker_execution'
4
+ require 'background_worker/logging'
5
+ require 'background_worker/state'
4
6
 
5
7
  module BackgroundWorker
6
8
  class Base
7
- attr_accessor :uid, :state
9
+ include ActiveSupport::Callbacks
10
+ include BackgroundWorker::Logging
11
+ include BackgroundWorker::State
12
+ attr_accessor :job_id, :options
13
+ define_callbacks :perform
14
+ define_callbacks :enqueue
8
15
 
9
16
  def initialize(options = {})
10
- @uid = options[:uid]
17
+ @options = options.symbolize_keys
18
+ @job_id = @options[:job_id] || SecureRandom.uuid
11
19
 
12
- # Store state persistently, to enable status checkups & progress reporting
13
- @state = BackgroundWorker::PersistentState.new(@uid, options.except(:uid))
14
20
  log("Created #{self.class}")
15
- log("Options are: #{options.inspect}")
21
+ log("Options are: #{@options.inspect}")
16
22
  end
17
23
 
18
- def perform
19
- raise AbstractError, 'Must be implemented in Job Class'
20
- end
21
-
22
- # Report progress...
23
- def report_progress(message)
24
- state.message = message
25
- state.save
26
- end
27
-
28
- # Report a minor progress -- may get called a lot, so don't save it so often
29
- def report_minor_progress(message)
30
- state.message = message
31
-
32
- # Only report minor events once per second
33
- @last_report ||= Time.now - 2
34
- time_elapsed = Time.now - @last_report
35
- return unless time_elapsed > 1
36
-
37
- @last_report = Time.now
38
- state.save
39
- end
40
-
41
- def report_successful(message = 'Finished successfully')
42
- state.set_completed(message, :successful)
43
- end
44
-
45
- def report_failed(message = 'Failed', detailed_message = nil)
46
- state.detailed_message = detailed_message
47
- state.set_completed(message, :failed)
48
- end
49
-
50
- def logger
51
- BackgroundWorker.logger
24
+ def perform_now(options)
25
+ run_callbacks :perform do
26
+ perform(options)
27
+ end
52
28
  end
53
29
 
54
- def log(message, options = {})
55
- severity = options.fetch(:severity, :info)
56
- logger.send(severity, "uid=#{uid} #{message}")
30
+ def enqueue(klass)
31
+ run_callbacks :enqueue do
32
+ BackgroundWorker.enqueue(klass, options.merge(job_id: job_id))
33
+ end
57
34
  end
58
35
 
59
36
  class << self
60
37
  attr_reader :queue
61
- def get_state_of(worker_id)
62
- BackgroundWorker::PersistentState.get_state_of(worker_id)
63
- end
64
38
 
65
39
  # Public method to do in background...
66
40
  def perform_later(options = {})
67
- opts = options.symbolize_keys
68
-
69
- opts[:uid] ||= BackgroundWorker::Uid.new(to_s).generate
70
-
71
- # Store into shared-cache before kicking job off
72
- BackgroundWorker::PersistentState.new(opts[:uid], opts.except(:uid))
73
-
41
+ worker = new(options)
74
42
  # Enqueue to the background queue
75
- BackgroundWorker.enqueue(self, opts)
76
-
77
- opts[:uid]
43
+ worker.enqueue(self)
44
+ worker
78
45
  end
79
46
 
80
47
  # This method is called by the job runner
81
- #
82
- # It will just call your preferred method in the worker.
83
48
  def perform_now(options = {})
84
49
  BackgroundWorker.verify_active_connections! if BackgroundWorker.config.backgrounded
85
50
 
86
51
  worker = new(options)
87
52
  execution = WorkerExecution.new(worker, options)
88
53
  execution.call
54
+ worker
89
55
  ensure
90
56
  BackgroundWorker.release_connections! if BackgroundWorker.config.backgrounded
91
57
  end
@@ -93,6 +59,22 @@ module BackgroundWorker
93
59
  def queue_as(queue = nil)
94
60
  @queue = queue&.to_sym || :default
95
61
  end
62
+
63
+ def before_perform(*filters, &blk)
64
+ set_callback(:perform, :before, *filters, &blk)
65
+ end
66
+
67
+ def after_perform(*filters, &blk)
68
+ set_callback(:perform, :after, *filters, &blk)
69
+ end
70
+
71
+ def before_enqueue(*filters, &blk)
72
+ set_callback(:enqueue, :before, *filters, &blk)
73
+ end
74
+
75
+ def after_enqueue(*filters, &blk)
76
+ set_callback(:enqueue, :after, *filters, &blk)
77
+ end
96
78
  end
97
79
  end
98
80
  end
@@ -0,0 +1,16 @@
1
+ require 'active_support/concern'
2
+
3
+ module BackgroundWorker
4
+ module Logging
5
+ extend ActiveSupport::Concern
6
+
7
+ def logger
8
+ BackgroundWorker.logger
9
+ end
10
+
11
+ def log(message, options = {})
12
+ severity = options.fetch(:severity, :info)
13
+ logger.send(severity, "job_id=#{job_id} #{message}")
14
+ end
15
+ end
16
+ end
@@ -7,12 +7,12 @@ module BackgroundWorker
7
7
  class PersistentState
8
8
  attr_accessor :message, :detailed_message, :status, :completed, :data
9
9
 
10
- def initialize(worker_uid, data)
10
+ def initialize(job_id, data)
11
11
  @message = 'Waiting for task to queue...'
12
12
  @status = :processing
13
13
  @completed = false
14
14
 
15
- @worker_uid = worker_uid
15
+ @job_id = job_id
16
16
  @data = data
17
17
  save
18
18
  end
@@ -27,13 +27,13 @@ module BackgroundWorker
27
27
 
28
28
  # Save persistently (well for an hour at least)
29
29
  def save
30
- Rails.cache.write(@worker_uid, generate_persistent_hash, expires_in: 1.hour)
30
+ Rails.cache.write(@job_id, generate_persistent_hash, expires_in: 1.hour)
31
31
  end
32
32
 
33
33
  # Get a report out the queue
34
34
  # (was .get_report, then .progress)
35
- def self.get_state_of(worker_uid)
36
- Rails.cache.read(worker_uid)
35
+ def self.get_state_of(job_id)
36
+ Rails.cache.read(job_id)
37
37
  end
38
38
 
39
39
  private
@@ -0,0 +1,47 @@
1
+ require 'active_support/concern'
2
+
3
+ module BackgroundWorker
4
+ module State
5
+ extend ActiveSupport::Concern
6
+ attr_accessor :state
7
+
8
+ # Report progress...
9
+ def report_progress(message)
10
+ state.message = message
11
+ state.save
12
+ end
13
+
14
+ # Report a minor progress -- may get called a lot, so don't save it so often
15
+ def report_minor_progress(message)
16
+ state.message = message
17
+
18
+ # Only report minor events once per second
19
+ @last_report ||= Time.now - 2
20
+ time_elapsed = Time.now - @last_report
21
+ return unless time_elapsed > 1
22
+
23
+ @last_report = Time.now
24
+ state.save
25
+ end
26
+
27
+ def report_successful(message = 'Finished successfully')
28
+ state.set_completed(message, :successful)
29
+ end
30
+
31
+ def report_failed(message = 'Failed', detailed_message = nil)
32
+ state.detailed_message = detailed_message
33
+ state.set_completed(message, :failed)
34
+ end
35
+
36
+ def state
37
+ # Store state persistently, to enable status checkups & progress reporting
38
+ @state ||= BackgroundWorker::PersistentState.new(job_id, @options)
39
+ end
40
+
41
+ module ClassMethods
42
+ def get_state_of(job_id)
43
+ BackgroundWorker::PersistentState.get_state_of(job_id)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module BackgroundWorker
2
- VERSION = '0.8.1'
2
+ VERSION = '0.9.0'
3
3
  end
@@ -3,13 +3,12 @@ module BackgroundWorker
3
3
  attr_reader :worker, :method_name, :options
4
4
 
5
5
  def initialize(worker, options)
6
- fail ArgumentError, "'uid' is required to identify worker" unless options[:uid].present?
7
6
  @worker = worker
8
7
  @options = options
9
8
  end
10
9
 
11
10
  def call
12
- worker.perform(options)
11
+ worker.perform_now(options)
13
12
  report_implicitly_successful unless completed?
14
13
 
15
14
  rescue StandardError => e
data/spec/base_spec.rb CHANGED
@@ -44,3 +44,51 @@ describe BackgroundWorker::Base do
44
44
  end
45
45
  end
46
46
  end
47
+
48
+ describe BackgroundWorker::Base do
49
+ describe 'callbacks' do
50
+ let(:cache) { double(write: nil, read: nil, reconnect: nil, store: nil) }
51
+ let(:model_class) { Model = Class.new(ActiveRecord::Base) }
52
+
53
+ let(:worker_class) {
54
+ Class.new(BackgroundWorker::Base) do
55
+ def perform(opts)
56
+ Rails.cache.store(opts[:value])
57
+ end
58
+
59
+ before_perform do
60
+ Rails.cache.store('before_perform_action')
61
+ end
62
+
63
+ after_perform do
64
+ Rails.cache.store('after_perform_action')
65
+ end
66
+
67
+ before_enqueue do
68
+ Rails.cache.store('before_enqueue_action')
69
+ end
70
+
71
+ after_enqueue do
72
+ Rails.cache.store('after_enqueue_action')
73
+ end
74
+ end
75
+ }
76
+
77
+ before do
78
+ stub_const 'Model', model_class
79
+ stub_const 'Rails', double(cache: cache, env: 'production')
80
+ BackgroundWorker.configure(backgrounded: false)
81
+ end
82
+
83
+ it 'should call perform callbacks' do
84
+ Model.transaction do
85
+ worker_class.perform_later(value: 42)
86
+ end
87
+ expect(cache).to have_received(:store).with('before_enqueue_action')
88
+ expect(cache).to have_received(:store).with('before_perform_action')
89
+ expect(cache).to have_received(:store).with(42)
90
+ expect(cache).to have_received(:store).with('after_perform_action')
91
+ expect(cache).to have_received(:store).with('after_enqueue_action')
92
+ end
93
+ end
94
+ end
@@ -1,3 +1,3 @@
1
1
  require 'coverage/kit'
2
2
 
3
- Coverage::Kit.setup(minimum_coverage: 82.30)
3
+ Coverage::Kit.setup(minimum_coverage: 84.60)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: background_worker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Noack
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-09-23 00:00:00.000000000 Z
13
+ date: 2022-09-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -152,15 +152,15 @@ files:
152
152
  - lib/background_worker.rb
153
153
  - lib/background_worker/base.rb
154
154
  - lib/background_worker/config.rb
155
+ - lib/background_worker/logging.rb
155
156
  - lib/background_worker/persistent_state.rb
156
- - lib/background_worker/uid.rb
157
+ - lib/background_worker/state.rb
157
158
  - lib/background_worker/version.rb
158
159
  - lib/background_worker/worker_execution.rb
159
160
  - spec/base_spec.rb
160
161
  - spec/schema.rb
161
162
  - spec/spec_helper.rb
162
163
  - spec/support/coverage_loader.rb
163
- - spec/uid_spec.rb
164
164
  homepage: http://github.com/sealink/background_worker
165
165
  licenses:
166
166
  - MIT
@@ -189,4 +189,3 @@ test_files:
189
189
  - spec/schema.rb
190
190
  - spec/spec_helper.rb
191
191
  - spec/support/coverage_loader.rb
192
- - spec/uid_spec.rb
@@ -1,24 +0,0 @@
1
- # Generates a unique identifier for a particular job identified by class_name/method
2
- module BackgroundWorker
3
- class Uid
4
- attr_reader :class_name
5
-
6
- def initialize(class_name)
7
- @class_name = class_name
8
- end
9
-
10
- def generate
11
- "#{generate_uid_name}:#{generate_uid_hash}"
12
- end
13
-
14
- private
15
-
16
- def generate_uid_hash
17
- ::Digest::MD5.hexdigest("#{class_name}:#{rand(1 << 64)}:#{Time.now}")
18
- end
19
-
20
- def generate_uid_name
21
- "#{class_name.underscore}".split('/').join(':')
22
- end
23
- end
24
- end
data/spec/uid_spec.rb DELETED
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe BackgroundWorker::Uid do
4
- let(:class_name) { 'CopyWorker' }
5
- let(:uid_object) { BackgroundWorker::Uid.new(class_name) }
6
-
7
- context '#generate' do
8
- subject(:uid) { uid_object.generate }
9
- it { is_expected.to match(/copy_worker:[0-9a-f]{16}/) }
10
- end
11
- end