workhorse 1.2.18 → 1.2.19
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/VERSION +1 -1
- data/lib/workhorse/performer.rb +28 -24
- data/lib/workhorse/poller.rb +49 -47
- data/lib/workhorse/pool.rb +6 -4
- data/lib/workhorse/worker.rb +15 -11
- data/workhorse.gemspec +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ee79a0aad4b594650de92485a2a0f4d95364042fe1ce8ebd4a2be075827d07d
|
4
|
+
data.tar.gz: a2dcfbdc9e1152513e9fb02613d1f219c3849f85797716e431f0a2fb84fae654
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99496e59a85fad0b8ca3fe3d9a24b4fd30fd8be3a9e0a236f584dffc42bfda37ba91a5224dfcd29aee88de72ea1df234df286262b5777daf9edb8cfffa0dc2f8
|
7
|
+
data.tar.gz: 13eee5ce97cfc0e66ef4b99a9132590230cc636d202f6e05e9757288dc0ba05e0fd916052bd3638464d0ecb0fafd868004fdc810c4f45f3d0a79350253a17b75
|
data/CHANGELOG.md
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.19
|
data/lib/workhorse/performer.rb
CHANGED
@@ -9,41 +9,45 @@ module Workhorse
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def perform
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
begin
|
13
|
+
fail 'Performer can only run once.' if @started
|
14
|
+
@started = true
|
15
|
+
perform!
|
16
|
+
rescue Exception => e
|
17
|
+
Workhorse.on_exception.call(e)
|
18
|
+
end
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
20
22
|
|
21
23
|
def perform!
|
22
|
-
|
24
|
+
begin
|
25
|
+
Thread.current[:workhorse_current_performer] = self
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
28
|
+
if defined?(Rails) && Rails.respond_to?(:application) && Rails.application && Rails.application.respond_to?(:executor)
|
29
|
+
Rails.application.executor.wrap do
|
30
|
+
perform_wrapped
|
31
|
+
end
|
32
|
+
else
|
27
33
|
perform_wrapped
|
28
34
|
end
|
29
|
-
else
|
30
|
-
perform_wrapped
|
31
35
|
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
log %(#{e.message}\n#{e.backtrace.join("\n")}), :error
|
36
|
+
rescue Exception => e
|
37
|
+
# ---------------------------------------------------------------
|
38
|
+
# Mark job as failed
|
39
|
+
# ---------------------------------------------------------------
|
40
|
+
log %(#{e.message}\n#{e.backtrace.join("\n")}), :error
|
38
41
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
42
|
+
Workhorse.tx_callback.call do
|
43
|
+
log 'Mark failed', :debug
|
44
|
+
@db_job.mark_failed!(e)
|
45
|
+
end
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
+
fail e
|
48
|
+
ensure
|
49
|
+
Thread.current[:workhorse_current_performer] = nil
|
50
|
+
end
|
47
51
|
end
|
48
52
|
|
49
53
|
def perform_wrapped
|
data/lib/workhorse/poller.rb
CHANGED
@@ -141,60 +141,62 @@ module Workhorse
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def with_global_lock(name: :workhorse, timeout: 2, &_block)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
144
|
+
begin
|
145
|
+
if @is_oracle
|
146
|
+
result = Workhorse::DbJob.connection.select_all(
|
147
|
+
"SELECT DBMS_LOCK.REQUEST(#{ORACLE_LOCK_HANDLE}, #{ORACLE_LOCK_MODE}, #{timeout}) FROM DUAL"
|
148
|
+
).first.values.last
|
148
149
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
150
|
+
success = result == 0
|
151
|
+
else
|
152
|
+
result = Workhorse::DbJob.connection.select_all(
|
153
|
+
"SELECT GET_LOCK(CONCAT(DATABASE(), '_#{name}'), #{timeout})"
|
154
|
+
).first.values.last
|
155
|
+
success = result == 1
|
156
|
+
end
|
156
157
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
158
|
+
if success
|
159
|
+
@global_lock_fails = 0
|
160
|
+
@max_global_lock_fails_reached = false
|
161
|
+
else
|
162
|
+
@global_lock_fails += 1
|
162
163
|
|
163
|
-
|
164
|
-
|
165
|
-
|
164
|
+
unless @max_global_lock_fails_reached
|
165
|
+
worker.log 'Could not obtain global lock, retrying with next poll.', :warn
|
166
|
+
end
|
166
167
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
168
|
+
if @global_lock_fails > Workhorse.max_global_lock_fails && !@max_global_lock_fails_reached
|
169
|
+
@max_global_lock_fails_reached = true
|
170
|
+
|
171
|
+
worker.log 'Could not obtain global lock, retrying with next poll. ' \
|
172
|
+
'This will be the last such message for this worker until ' \
|
173
|
+
'the issue is resolved.', :warn
|
174
|
+
|
175
|
+
message = "Worker reached maximum number of consecutive times (#{Workhorse.max_global_lock_fails}) " \
|
176
|
+
"where the global lock could no be acquired within the specified timeout (#{timeout}). " \
|
177
|
+
'A worker that obtained this lock may have crashed without ending the database ' \
|
178
|
+
'connection properly. On MySQL, use "show processlist;" to see which connection(s) ' \
|
179
|
+
'is / are holding the lock for a long period of time and consider killing them using ' \
|
180
|
+
"MySQL's \"kill <Id>\" command. This message will be issued only once per worker " \
|
181
|
+
'and may only be re-triggered if the error happens again *after* the lock has ' \
|
182
|
+
'been solved in the meantime.'
|
183
|
+
|
184
|
+
worker.log message
|
185
|
+
exception = StandardError.new(message)
|
186
|
+
Workhorse.on_exception.call(exception)
|
187
|
+
end
|
186
188
|
end
|
187
|
-
end
|
188
189
|
|
189
|
-
|
190
|
+
return unless success
|
190
191
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
192
|
+
yield
|
193
|
+
ensure
|
194
|
+
if success
|
195
|
+
if @is_oracle
|
196
|
+
Workhorse::DbJob.connection.execute("SELECT DBMS_LOCK.RELEASE(#{ORACLE_LOCK_HANDLE}) FROM DUAL")
|
197
|
+
else
|
198
|
+
Workhorse::DbJob.connection.execute("SELECT RELEASE_LOCK(CONCAT(DATABASE(), '_#{name}'))")
|
199
|
+
end
|
198
200
|
end
|
199
201
|
end
|
200
202
|
end
|
data/lib/workhorse/pool.rb
CHANGED
@@ -34,10 +34,12 @@ module Workhorse
|
|
34
34
|
active_threads.increment
|
35
35
|
|
36
36
|
@executor.post do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
begin
|
38
|
+
yield
|
39
|
+
ensure
|
40
|
+
active_threads.decrement
|
41
|
+
@on_idle.try(:call)
|
42
|
+
end
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
data/lib/workhorse/worker.rb
CHANGED
@@ -144,19 +144,23 @@ module Workhorse
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def perform(db_job_id)
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
147
|
+
begin
|
148
|
+
mutex.synchronize do
|
149
|
+
assert_state! :running
|
150
|
+
log "Posting job #{db_job_id} to thread pool"
|
151
|
+
|
152
|
+
@pool.post do
|
153
|
+
begin
|
154
|
+
Workhorse::Performer.new(db_job_id, self).perform
|
155
|
+
rescue Exception => e
|
156
|
+
log %(#{e.message}\n#{e.backtrace.join("\n")}), :error
|
157
|
+
Workhorse.on_exception.call(e)
|
158
|
+
end
|
159
|
+
end
|
156
160
|
end
|
161
|
+
rescue Exception => e
|
162
|
+
Workhorse.on_exception.call(e)
|
157
163
|
end
|
158
|
-
rescue Exception => e
|
159
|
-
Workhorse.on_exception.call(e)
|
160
164
|
end
|
161
165
|
|
162
166
|
private
|
data/workhorse.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: workhorse 1.2.
|
2
|
+
# stub: workhorse 1.2.19 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "workhorse".freeze
|
6
|
-
s.version = "1.2.
|
6
|
+
s.version = "1.2.19"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|