workhorse 1.2.17 → 1.2.19

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: 7c3223be9f4d677fa59d215519c9b96e933e5ab37f3ad96e904cd6dc91b59488
4
- data.tar.gz: c30eaa0c15cd8785caf0aab8800de9c8838ff62d9192e1d8d9e8a386659322e1
3
+ metadata.gz: 4ee79a0aad4b594650de92485a2a0f4d95364042fe1ce8ebd4a2be075827d07d
4
+ data.tar.gz: a2dcfbdc9e1152513e9fb02613d1f219c3849f85797716e431f0a2fb84fae654
5
5
  SHA512:
6
- metadata.gz: 9d79e67c853bf5b258ccc2d334de5c746c046b6fca063907cdc3e0a8693e641d12cbefb3ce408f69f697dd1b8f7b0ee4e6ccfcd98ed4b86210786ee53bf23e01
7
- data.tar.gz: eca0f05a85ed9a9afaeb0d146b8243b02c3d8bd5cf1229488eacae4437494df1554ce7c2f0cf2f97118b8024d2698d6d054aef3039ab19a253497e4a6caab54f
6
+ metadata.gz: 99496e59a85fad0b8ca3fe3d9a24b4fd30fd8be3a9e0a236f584dffc42bfda37ba91a5224dfcd29aee88de72ea1df234df286262b5777daf9edb8cfffa0dc2f8
7
+ data.tar.gz: 13eee5ce97cfc0e66ef4b99a9132590230cc636d202f6e05e9757288dc0ba05e0fd916052bd3638464d0ecb0fafd868004fdc810c4f45f3d0a79350253a17b75
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Workhorse Changelog
2
2
 
3
+ ## 1.2.19 - 2024-05-07
4
+
5
+ * Fix further compatibility issues with `ruby < 2.5`
6
+
7
+ Sitrox reference: #124538.
8
+
9
+ ## 1.2.18 - 2024-05-07
10
+
11
+ * Fix compatibility with `ruby < 2.5`
12
+
13
+ Sitrox reference: #124538.
14
+
3
15
  ## 1.2.17 - 2024-02-21
4
16
 
5
17
  * Stable release based on previous RC releases.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.17
1
+ 1.2.19
@@ -9,41 +9,45 @@ module Workhorse
9
9
  end
10
10
 
11
11
  def perform
12
- fail 'Performer can only run once.' if @started
13
- @started = true
14
- perform!
15
- rescue Exception => e
16
- Workhorse.on_exception.call(e)
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
- Thread.current[:workhorse_current_performer] = self
24
+ begin
25
+ Thread.current[:workhorse_current_performer] = self
23
26
 
24
- ActiveRecord::Base.connection_pool.with_connection do
25
- if defined?(Rails) && Rails.respond_to?(:application) && Rails.application && Rails.application.respond_to?(:executor)
26
- Rails.application.executor.wrap do
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
- end
33
- rescue Exception => e
34
- # ---------------------------------------------------------------
35
- # Mark job as failed
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
- Workhorse.tx_callback.call do
40
- log 'Mark failed', :debug
41
- @db_job.mark_failed!(e)
42
- end
42
+ Workhorse.tx_callback.call do
43
+ log 'Mark failed', :debug
44
+ @db_job.mark_failed!(e)
45
+ end
43
46
 
44
- fail e
45
- ensure
46
- Thread.current[:workhorse_current_performer] = nil
47
+ fail e
48
+ ensure
49
+ Thread.current[:workhorse_current_performer] = nil
50
+ end
47
51
  end
48
52
 
49
53
  def perform_wrapped
@@ -92,10 +92,12 @@ module Workhorse
92
92
 
93
93
  # Get pids without active process
94
94
  orphaned_pids = job_pids.select do |pid|
95
- Process.getpgid(pid)
96
- false
97
- rescue Errno::ESRCH
98
- true
95
+ begin
96
+ Process.getpgid(pid)
97
+ false
98
+ rescue Errno::ESRCH
99
+ true
100
+ end
99
101
  end
100
102
 
101
103
  # Reset jobs in state 'locked'
@@ -139,60 +141,62 @@ module Workhorse
139
141
  end
140
142
 
141
143
  def with_global_lock(name: :workhorse, timeout: 2, &_block)
142
- if @is_oracle
143
- result = Workhorse::DbJob.connection.select_all(
144
- "SELECT DBMS_LOCK.REQUEST(#{ORACLE_LOCK_HANDLE}, #{ORACLE_LOCK_MODE}, #{timeout}) FROM DUAL"
145
- ).first.values.last
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
146
149
 
147
- success = result == 0
148
- else
149
- result = Workhorse::DbJob.connection.select_all(
150
- "SELECT GET_LOCK(CONCAT(DATABASE(), '_#{name}'), #{timeout})"
151
- ).first.values.last
152
- success = result == 1
153
- end
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
154
157
 
155
- if success
156
- @global_lock_fails = 0
157
- @max_global_lock_fails_reached = false
158
- else
159
- @global_lock_fails += 1
158
+ if success
159
+ @global_lock_fails = 0
160
+ @max_global_lock_fails_reached = false
161
+ else
162
+ @global_lock_fails += 1
160
163
 
161
- unless @max_global_lock_fails_reached
162
- worker.log 'Could not obtain global lock, retrying with next poll.', :warn
163
- end
164
+ unless @max_global_lock_fails_reached
165
+ worker.log 'Could not obtain global lock, retrying with next poll.', :warn
166
+ end
164
167
 
165
- if @global_lock_fails > Workhorse.max_global_lock_fails && !@max_global_lock_fails_reached
166
- @max_global_lock_fails_reached = true
167
-
168
- worker.log 'Could not obtain global lock, retrying with next poll. ' \
169
- 'This will be the last such message for this worker until ' \
170
- 'the issue is resolved.', :warn
171
-
172
- message = "Worker reached maximum number of consecutive times (#{Workhorse.max_global_lock_fails}) " \
173
- "where the global lock could no be acquired within the specified timeout (#{timeout}). " \
174
- 'A worker that obtained this lock may have crashed without ending the database ' \
175
- 'connection properly. On MySQL, use "show processlist;" to see which connection(s) ' \
176
- 'is / are holding the lock for a long period of time and consider killing them using ' \
177
- "MySQL's \"kill <Id>\" command. This message will be issued only once per worker " \
178
- 'and may only be re-triggered if the error happens again *after* the lock has ' \
179
- 'been solved in the meantime.'
180
-
181
- worker.log message
182
- exception = StandardError.new(message)
183
- Workhorse.on_exception.call(exception)
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
184
188
  end
185
- end
186
189
 
187
- return unless success
190
+ return unless success
188
191
 
189
- yield
190
- ensure
191
- if success
192
- if @is_oracle
193
- Workhorse::DbJob.connection.execute("SELECT DBMS_LOCK.RELEASE(#{ORACLE_LOCK_HANDLE}) FROM DUAL")
194
- else
195
- Workhorse::DbJob.connection.execute("SELECT RELEASE_LOCK(CONCAT(DATABASE(), '_#{name}'))")
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
196
200
  end
197
201
  end
198
202
  end
@@ -34,10 +34,12 @@ module Workhorse
34
34
  active_threads.increment
35
35
 
36
36
  @executor.post do
37
- yield
38
- ensure
39
- active_threads.decrement
40
- @on_idle.try(:call)
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
@@ -144,19 +144,23 @@ module Workhorse
144
144
  end
145
145
 
146
146
  def perform(db_job_id)
147
- mutex.synchronize do
148
- assert_state! :running
149
- log "Posting job #{db_job_id} to thread pool"
150
-
151
- @pool.post do
152
- Workhorse::Performer.new(db_job_id, self).perform
153
- rescue Exception => e
154
- log %(#{e.message}\n#{e.backtrace.join("\n")}), :error
155
- Workhorse.on_exception.call(e)
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,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: workhorse 1.2.17 ruby lib
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.17"
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]
10
10
  s.authors = ["Sitrox".freeze]
11
- s.date = "2024-02-21"
11
+ s.date = "2024-05-07"
12
12
  s.files = [".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, "CHANGELOG.md".freeze, "FAQ.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/rubocop".freeze, "lib/active_job/queue_adapters/workhorse_adapter.rb".freeze, "lib/generators/workhorse/install_generator.rb".freeze, "lib/generators/workhorse/templates/bin/workhorse.rb".freeze, "lib/generators/workhorse/templates/config/initializers/workhorse.rb".freeze, "lib/generators/workhorse/templates/create_table_jobs.rb".freeze, "lib/workhorse.rb".freeze, "lib/workhorse/active_job_extension.rb".freeze, "lib/workhorse/daemon.rb".freeze, "lib/workhorse/daemon/shell_handler.rb".freeze, "lib/workhorse/db_job.rb".freeze, "lib/workhorse/enqueuer.rb".freeze, "lib/workhorse/jobs/cleanup_succeeded_jobs.rb".freeze, "lib/workhorse/jobs/detect_stale_jobs_job.rb".freeze, "lib/workhorse/jobs/run_active_job.rb".freeze, "lib/workhorse/jobs/run_rails_op.rb".freeze, "lib/workhorse/performer.rb".freeze, "lib/workhorse/poller.rb".freeze, "lib/workhorse/pool.rb".freeze, "lib/workhorse/scoped_env.rb".freeze, "lib/workhorse/worker.rb".freeze, "test/active_job/queue_adapters/workhorse_adapter_test.rb".freeze, "test/lib/db_schema.rb".freeze, "test/lib/jobs.rb".freeze, "test/lib/test_helper.rb".freeze, "test/workhorse/daemon_test.rb".freeze, "test/workhorse/db_job_test.rb".freeze, "test/workhorse/enqueuer_test.rb".freeze, "test/workhorse/performer_test.rb".freeze, "test/workhorse/poller_test.rb".freeze, "test/workhorse/pool_test.rb".freeze, "test/workhorse/worker_test.rb".freeze, "workhorse.gemspec".freeze]
13
13
  s.rubygems_version = "3.4.6".freeze
14
14
  s.summary = "Multi-threaded job backend with database queuing for ruby.".freeze
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workhorse
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.17
4
+ version: 1.2.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sitrox
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-21 00:00:00.000000000 Z
11
+ date: 2024-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -178,8 +178,8 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- description:
182
- email:
181
+ description:
182
+ email:
183
183
  executables: []
184
184
  extensions: []
185
185
  extra_rdoc_files: []
@@ -229,10 +229,10 @@ files:
229
229
  - test/workhorse/pool_test.rb
230
230
  - test/workhorse/worker_test.rb
231
231
  - workhorse.gemspec
232
- homepage:
232
+ homepage:
233
233
  licenses: []
234
234
  metadata: {}
235
- post_install_message:
235
+ post_install_message:
236
236
  rdoc_options: []
237
237
  require_paths:
238
238
  - lib
@@ -247,8 +247,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
247
247
  - !ruby/object:Gem::Version
248
248
  version: '0'
249
249
  requirements: []
250
- rubygems_version: 3.4.6
251
- signing_key:
250
+ rubygems_version: 3.5.4
251
+ signing_key:
252
252
  specification_version: 4
253
253
  summary: Multi-threaded job backend with database queuing for ruby.
254
254
  test_files: