background_worker 0.8.1 → 0.9.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: 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