workhorse 1.2.18 → 1.2.20

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: ec60662cb949157cad7c1c42704bff8299505f75ac993dc3fb4f95e0cb645e6a
4
- data.tar.gz: 80d7fff31444778438ebc47c68e54d6a9291f4b7e68f2eaae30dc50d087d4fb2
3
+ metadata.gz: 5779f0370ad5f8c4c99389c7c089d45d68820e9f63703a7886b9b702ba3b9fd3
4
+ data.tar.gz: fd220b5a403be4a901446b9a1bc55d6acfaf8e6b5302a205d79a20f47951c6cf
5
5
  SHA512:
6
- metadata.gz: c9e7940d6d0a38de896ca31a892a5fe4e9d08a607969ff998c916e1688353e4c8264267bc9f45725bfd0a00a5f2b8285748326151b343d24d54e18e20cba0021
7
- data.tar.gz: b3c9d6a97f5d90811ea16fe1222b7608feeebefb78d777abd22c831a60fa3a3ec89aed4cbf374779dca959cb3e64a6030802bf909b82125f8db79f2f44d08c4c
6
+ metadata.gz: 66a64fc3dc59ed726cb7cdc4774c979bcfafb1246c67e52cac74ff87da9509369fababe6d294fb9943ad8c42a97a41d955277ae07b91e9491f07618a530d6dff
7
+ data.tar.gz: 1264727996bd00beb9d0f0968e82e34de174ee1529977f55ae87a5a47ec4a70d7c8caa93a3ed78e9816740fb894d748b022a1fe574303f63f9c497a2abf3454b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Workhorse Changelog
2
2
 
3
+ ## 1.2.20 - 2024-06-17
4
+
5
+ * Fix rails environment check
6
+
7
+ Sitrox reference: #125593.
8
+
9
+ ## 1.2.19 - 2024-05-07
10
+
11
+ * Fix further compatibility issues with `ruby < 2.5`
12
+
13
+ Sitrox reference: #124538.
14
+
3
15
  ## 1.2.18 - 2024-05-07
4
16
 
5
17
  * Fix compatibility with `ruby < 2.5`
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.18
1
+ 1.2.20
@@ -168,6 +168,8 @@ module Workhorse
168
168
  end
169
169
 
170
170
  def start_worker(worker)
171
+ check_rails_env if defined?(Rails)
172
+
171
173
  pid = fork do
172
174
  $0 = process_name(worker)
173
175
  # Reopen pipes to prevent #107576
@@ -244,5 +246,11 @@ module Workhorse
244
246
 
245
247
  return file, pid, active
246
248
  end
249
+
250
+ def check_rails_env
251
+ unless Rails.env.production?
252
+ warn 'WARNING: Always run workhorse workers in production environment. Other environments can lead to unexpected behavior.'
253
+ end
254
+ end
247
255
  end
248
256
  end
@@ -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
@@ -141,60 +141,62 @@ module Workhorse
141
141
  end
142
142
 
143
143
  def with_global_lock(name: :workhorse, timeout: 2, &_block)
144
- if @is_oracle
145
- result = Workhorse::DbJob.connection.select_all(
146
- "SELECT DBMS_LOCK.REQUEST(#{ORACLE_LOCK_HANDLE}, #{ORACLE_LOCK_MODE}, #{timeout}) FROM DUAL"
147
- ).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
148
149
 
149
- success = result == 0
150
- else
151
- result = Workhorse::DbJob.connection.select_all(
152
- "SELECT GET_LOCK(CONCAT(DATABASE(), '_#{name}'), #{timeout})"
153
- ).first.values.last
154
- success = result == 1
155
- 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
156
157
 
157
- if success
158
- @global_lock_fails = 0
159
- @max_global_lock_fails_reached = false
160
- else
161
- @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
162
163
 
163
- unless @max_global_lock_fails_reached
164
- worker.log 'Could not obtain global lock, retrying with next poll.', :warn
165
- end
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
- if @global_lock_fails > Workhorse.max_global_lock_fails && !@max_global_lock_fails_reached
168
- @max_global_lock_fails_reached = true
169
-
170
- worker.log 'Could not obtain global lock, retrying with next poll. ' \
171
- 'This will be the last such message for this worker until ' \
172
- 'the issue is resolved.', :warn
173
-
174
- message = "Worker reached maximum number of consecutive times (#{Workhorse.max_global_lock_fails}) " \
175
- "where the global lock could no be acquired within the specified timeout (#{timeout}). " \
176
- 'A worker that obtained this lock may have crashed without ending the database ' \
177
- 'connection properly. On MySQL, use "show processlist;" to see which connection(s) ' \
178
- 'is / are holding the lock for a long period of time and consider killing them using ' \
179
- "MySQL's \"kill <Id>\" command. This message will be issued only once per worker " \
180
- 'and may only be re-triggered if the error happens again *after* the lock has ' \
181
- 'been solved in the meantime.'
182
-
183
- worker.log message
184
- exception = StandardError.new(message)
185
- 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
186
188
  end
187
- end
188
189
 
189
- return unless success
190
+ return unless success
190
191
 
191
- yield
192
- ensure
193
- if success
194
- if @is_oracle
195
- Workhorse::DbJob.connection.execute("SELECT DBMS_LOCK.RELEASE(#{ORACLE_LOCK_HANDLE}) FROM DUAL")
196
- else
197
- 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
198
200
  end
199
201
  end
200
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
@@ -67,8 +67,6 @@ module Workhorse
67
67
  if instant_repolling
68
68
  @pool.on_idle { @poller.instant_repoll! }
69
69
  end
70
-
71
- check_rails_env if defined?(Rails)
72
70
  end
73
71
 
74
72
  def log(text, level = :info)
@@ -144,19 +142,23 @@ module Workhorse
144
142
  end
145
143
 
146
144
  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)
145
+ begin
146
+ mutex.synchronize do
147
+ assert_state! :running
148
+ log "Posting job #{db_job_id} to thread pool"
149
+
150
+ @pool.post do
151
+ begin
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)
156
+ end
157
+ end
156
158
  end
159
+ rescue Exception => e
160
+ Workhorse.on_exception.call(e)
157
161
  end
158
- rescue Exception => e
159
- Workhorse.on_exception.call(e)
160
162
  end
161
163
 
162
164
  private
@@ -192,12 +194,6 @@ module Workhorse
192
194
  return mem.to_i / 1024
193
195
  end
194
196
 
195
- def check_rails_env
196
- unless Rails.env.production?
197
- warn 'WARNING: Always run workhorse workers in production environment. Other environments can lead to unexpected behavior.'
198
- end
199
- end
200
-
201
197
  def trap_log_reopen
202
198
  Signal.trap(LOG_REOPEN_SIGNAL) do
203
199
  Thread.new do
data/workhorse.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: workhorse 1.2.18 ruby lib
2
+ # stub: workhorse 1.2.20 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "workhorse".freeze
6
- s.version = "1.2.18"
6
+ s.version = "1.2.20"
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-05-07"
11
+ s.date = "2024-06-17"
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.18
4
+ version: 1.2.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sitrox
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-07 00:00:00.000000000 Z
11
+ date: 2024-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler