solid_terminator 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +27 -0
- data/README.md +25 -4
- data/lib/generators/solid_terminator/install_generator.rb +4 -0
- data/lib/generators/solid_terminator/templates/add_arguments_to_solid_queue_terminated_executions.rb +18 -0
- data/lib/generators/solid_terminator/update_generator.rb +19 -0
- data/lib/solid_terminator/engine.rb +5 -4
- data/lib/solid_terminator/job_terminated.rb +1 -0
- data/lib/solid_terminator/monitor.rb +4 -10
- data/lib/solid_terminator/terminable.rb +26 -12
- data/lib/solid_terminator/terminated_execution.rb +26 -2
- data/lib/solid_terminator/thread_registry.rb +15 -0
- data/lib/solid_terminator/version.rb +1 -1
- metadata +36 -7
- data/lib/solid_terminator/claimed_execution_patch.rb +0 -32
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 289534896466bc08b1f8a285c12c1ef406cd00a6d3941396cad7b366a20061b8
|
|
4
|
+
data.tar.gz: 8237d1db3ff4ce1e5e200ee97350936b38e62a52c9f170693d5b66d50daa9b3d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63bf381c2e3602eb6e42e373bcfa708eeab2e2c8f81fbd46eeba03f60869950501cb7670860d59e28208d6dd1983b42eddd15c4060c7f58f43147f6c58d7a7d1
|
|
7
|
+
data.tar.gz: 80eb8f57d9ff1dd4ff24658cd8575e6ebfb0a928dda0899f917f6a2da481fe6c33da6a62588858538b754a88155ccacf4791ca3d8d87582c2618370031a02b0d
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.2.0] - 2026-10-10
|
|
6
|
+
|
|
7
|
+
### Upgrading
|
|
8
|
+
|
|
9
|
+
Run `bin/rails generate solid_terminator:update` and migrate. This adds the `arguments` column to `solid_queue_terminated_executions`.
|
|
10
|
+
|
|
11
|
+
### Breaking
|
|
12
|
+
|
|
13
|
+
- Requires a new migration that adds `arguments` to `solid_queue_terminated_executions` (see Upgrading). Until it runs, terminated executions are recorded without their arguments and cannot be retried. Workers log an error at startup and on every termination while the migration is missing.
|
|
14
|
+
- `perform_now` on a terminated job no longer raises `SolidTerminator::JobTerminated`. `Terminable` now handles it with `rescue_from`, so the job returns normally and SolidQueue marks it finished.
|
|
15
|
+
- Removed `SolidTerminator::ClaimedExecutionPatch`. SolidTerminator no longer patches SolidQueue internals.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `bin/rails generate solid_terminator:update` copies only the migrations the app is missing, without touching the initializer.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Depends on `activejob`, `activerecord` and `railties` instead of the whole `rails` gem.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- `NameError: undefined local variable or method 'unblock_next_job'` raised after every job on solid_queue >= 1.5.0.
|
|
28
|
+
- `SolidQueue::TerminatedExecution#retry` failed once SolidQueue cleared the finished job (immediately with `preserve_finished_jobs = false`, otherwise after `clear_finished_jobs_after`). The job's arguments are now stored on the terminated execution.
|
|
29
|
+
- `SolidQueue::TerminatedExecution#retry` raised `NoMethodError: undefined method '[]' for nil` on executions recorded before 0.2.0 whose job was already cleared. It now raises `SolidQueue::TerminatedExecution::NotRetryable` with an explanation.
|
|
30
|
+
- A termination could hit the wrong job: if the targeted job finished just as the monitor signalled it, `JobTerminated` could land in the next job on the same worker thread, or interrupt cleanup and leave a stale registry entry that kept signalling that thread. The monitor now raises under the registry lock, and `Terminable` only accepts the signal while the job's own code runs.
|
|
31
|
+
|
|
5
32
|
## [0.1.0] - 2026-06-06
|
|
6
33
|
|
|
7
34
|
- Initial release
|
data/README.md
CHANGED
|
@@ -36,7 +36,7 @@ Run the install generator:
|
|
|
36
36
|
bin/rails generate solid_terminator:install
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
This copies
|
|
39
|
+
This copies three migrations and an initializer. Then run migrations.
|
|
40
40
|
|
|
41
41
|
**Single-database apps** (SolidQueue shares the main database):
|
|
42
42
|
|
|
@@ -62,6 +62,22 @@ The generator creates two tables:
|
|
|
62
62
|
| `solid_queue_terminations` | Termination signal — almost always empty |
|
|
63
63
|
| `solid_queue_terminated_executions` | Audit trail of every terminated job |
|
|
64
64
|
|
|
65
|
+
### Upgrading from 0.1
|
|
66
|
+
|
|
67
|
+
Run the update generator to copy only the migrations your app is missing, then run migrations as above:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
bin/rails generate solid_terminator:update
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
It takes the same `--database` option as `install`. Run it after every upgrade; when nothing is missing it does nothing.
|
|
74
|
+
|
|
75
|
+
Until the migrations run, workers log an error at startup and on every termination that names this command.
|
|
76
|
+
|
|
77
|
+
The migration adds an `arguments` column to `solid_queue_terminated_executions` and copies it from jobs SolidQueue still has. Terminated executions whose job SolidQueue already cleared cannot be retried.
|
|
78
|
+
|
|
79
|
+
0.2 also changes behaviour: `perform_now` on a terminated job no longer raises `SolidTerminator::JobTerminated`. See the [changelog](CHANGELOG.md).
|
|
80
|
+
|
|
65
81
|
## Usage
|
|
66
82
|
|
|
67
83
|
### Make a job terminable
|
|
@@ -159,6 +175,8 @@ SolidQueue::Job.where(class_name: 'MyJob').pluck(:active_job_id)
|
|
|
159
175
|
|
|
160
176
|
When a job is terminated, SolidTerminator writes a `SolidQueue::TerminatedExecution` record so you have a queryable audit trail.
|
|
161
177
|
|
|
178
|
+
> **Note:** SolidQueue has no "terminated" state, so it records a terminated job as **finished**, the same as a job that succeeded. Mission Control and `SolidQueue::Job.finished` include terminated jobs. Use `SolidQueue::TerminatedExecution` to tell them apart.
|
|
179
|
+
|
|
162
180
|
### Query
|
|
163
181
|
|
|
164
182
|
```ruby
|
|
@@ -169,7 +187,7 @@ SolidQueue::TerminatedExecution.ordered
|
|
|
169
187
|
SolidQueue::TerminatedExecution.where(queue_name: 'critical')
|
|
170
188
|
```
|
|
171
189
|
|
|
172
|
-
Each record exposes: `job_id`, `queue_name`, `priority`, `terminated_at`.
|
|
190
|
+
Each record exposes: `job_id`, `queue_name`, `priority`, `arguments`, `terminated_at`.
|
|
173
191
|
|
|
174
192
|
### Retry a terminated job
|
|
175
193
|
|
|
@@ -179,7 +197,9 @@ Re-enqueue the original job with its original arguments:
|
|
|
179
197
|
SolidQueue::TerminatedExecution.find_by(job_id: sq_job_id).retry
|
|
180
198
|
```
|
|
181
199
|
|
|
182
|
-
This destroys the `TerminatedExecution` record and enqueues a new job in a single transaction.
|
|
200
|
+
This destroys the `TerminatedExecution` record and enqueues a new job in a single transaction. The job's arguments are stored on the `TerminatedExecution`, so retry still works after SolidQueue clears the finished job.
|
|
201
|
+
|
|
202
|
+
Executions recorded before 0.2.0 whose job was already cleared have no `arguments`. `retry` raises `SolidQueue::TerminatedExecution::NotRetryable` for them. Delete them instead.
|
|
183
203
|
|
|
184
204
|
## Configuration
|
|
185
205
|
|
|
@@ -252,7 +272,8 @@ Planned improvements — no particular order:
|
|
|
252
272
|
|
|
253
273
|
```bash
|
|
254
274
|
bundle install
|
|
255
|
-
bundle exec rspec # run tests
|
|
275
|
+
bundle exec rspec # run unit tests
|
|
276
|
+
bundle exec rspec integration # run against real SolidQueue models
|
|
256
277
|
bundle exec rubocop # lint
|
|
257
278
|
bundle exec rubocop -A # lint with auto-fix
|
|
258
279
|
```
|
|
@@ -27,6 +27,10 @@ module SolidTerminator
|
|
|
27
27
|
migration_template \
|
|
28
28
|
'create_solid_queue_terminated_executions.rb',
|
|
29
29
|
File.join(target_migrations_dir, 'create_solid_queue_terminated_executions.rb')
|
|
30
|
+
|
|
31
|
+
migration_template \
|
|
32
|
+
'add_arguments_to_solid_queue_terminated_executions.rb',
|
|
33
|
+
File.join(target_migrations_dir, 'add_arguments_to_solid_queue_terminated_executions.rb')
|
|
30
34
|
end
|
|
31
35
|
|
|
32
36
|
def create_initializer
|
data/lib/generators/solid_terminator/templates/add_arguments_to_solid_queue_terminated_executions.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class AddArgumentsToSolidQueueTerminatedExecutions < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def up
|
|
3
|
+
add_column :solid_queue_terminated_executions, :arguments, :text
|
|
4
|
+
|
|
5
|
+
# Copy from jobs SolidQueue has not cleared yet; rows whose job is already gone stay NULL and cannot be retried.
|
|
6
|
+
execute <<~SQL
|
|
7
|
+
UPDATE solid_queue_terminated_executions
|
|
8
|
+
SET arguments = (
|
|
9
|
+
SELECT solid_queue_jobs.arguments FROM solid_queue_jobs
|
|
10
|
+
WHERE solid_queue_jobs.id = solid_queue_terminated_executions.job_id
|
|
11
|
+
)
|
|
12
|
+
SQL
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def down
|
|
16
|
+
remove_column :solid_queue_terminated_executions, :arguments
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'install_generator'
|
|
4
|
+
|
|
5
|
+
module SolidTerminator
|
|
6
|
+
module Generators
|
|
7
|
+
class UpdateGenerator < InstallGenerator
|
|
8
|
+
source_root File.expand_path('templates', __dir__)
|
|
9
|
+
|
|
10
|
+
remove_command :create_initializer
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def migration_template(source, destination, config = {})
|
|
15
|
+
super(source, destination, config.merge(skip: true))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -7,14 +7,15 @@ module SolidTerminator
|
|
|
7
7
|
config.to_prepare do
|
|
8
8
|
require 'solid_terminator/termination'
|
|
9
9
|
require 'solid_terminator/terminated_execution'
|
|
10
|
-
require 'solid_terminator/claimed_execution_patch'
|
|
11
|
-
SolidQueue::ClaimedExecution.prepend(SolidTerminator::ClaimedExecutionPatch)
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
config.after_initialize do
|
|
15
13
|
if defined?(SolidQueue)
|
|
16
|
-
SolidQueue.on_worker_start
|
|
17
|
-
|
|
14
|
+
SolidQueue.on_worker_start do
|
|
15
|
+
SolidQueue::TerminatedExecution.log_unless_migrated
|
|
16
|
+
SolidTerminator.start_monitor
|
|
17
|
+
end
|
|
18
|
+
SolidQueue.on_worker_stop { SolidTerminator.stop_monitor }
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
end
|
|
@@ -70,16 +70,10 @@ module SolidTerminator
|
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
def signal_termination(termination)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
logger.info("Raising termination on job #{termination.active_job_id}")
|
|
79
|
-
begin
|
|
80
|
-
thread.raise(JobTerminated, "Job #{termination.active_job_id} terminated")
|
|
81
|
-
rescue ThreadError
|
|
82
|
-
logger.warn("Thread for job #{termination.active_job_id} died before signal; will retry next poll")
|
|
73
|
+
job_id = termination.active_job_id
|
|
74
|
+
case ThreadRegistry.raise_in(job_id, JobTerminated, "Job #{job_id} terminated")
|
|
75
|
+
when :raised then logger.info("Raised termination on job #{job_id}")
|
|
76
|
+
when :dead then clean_stale_entry(termination)
|
|
83
77
|
end
|
|
84
78
|
# Row stays: job's ensure deletes it on clean exit; if the job swallows the exception
|
|
85
79
|
# the row persists so the monitor retries next poll rather than silently giving up.
|
|
@@ -6,33 +6,47 @@ module SolidTerminator
|
|
|
6
6
|
|
|
7
7
|
included do
|
|
8
8
|
around_perform :with_termination_handling
|
|
9
|
+
# rescue_from rather than rescuing in around_perform: perform_now then returns normally, so
|
|
10
|
+
# SolidQueue marks the job finished, and after_perform callbacks from parent classes do not run.
|
|
11
|
+
rescue_from(JobTerminated) { |error| handle_job_terminated(error) }
|
|
9
12
|
end
|
|
10
13
|
|
|
11
14
|
private
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
# JobTerminated is only delivered while the job's own code runs. During registration and cleanup
|
|
17
|
+
# it is deferred, so a signal cannot interrupt deregister and leave a stale entry that would make
|
|
18
|
+
# the monitor raise into the next job on this pool thread.
|
|
19
|
+
def with_termination_handling(&)
|
|
14
20
|
current_thread = Thread.current
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
Thread.handle_interrupt(JobTerminated => :never) do
|
|
22
|
+
ThreadRegistry.register(job_id)
|
|
23
|
+
st_logger.debug("Job #{job_id} registered for termination monitoring")
|
|
24
|
+
Thread.handle_interrupt(JobTerminated => :immediate, &)
|
|
25
|
+
ensure
|
|
26
|
+
finish_termination_handling(current_thread)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def finish_termination_handling(current_thread)
|
|
21
31
|
ThreadRegistry.deregister(job_id, current_thread)
|
|
22
32
|
st_logger.debug("Job #{job_id} deregistered from termination monitoring")
|
|
23
33
|
cleanup_termination_row
|
|
34
|
+
discard_pending_termination
|
|
24
35
|
end
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
# A signal sent just before deregister is still queued. The job is over either way, so drop it
|
|
38
|
+
# instead of letting it fire after the mask lifts and mark a completed job as terminated.
|
|
39
|
+
# Unmasking delivers any queued signal; no Thread.pending_interrupt?(JobTerminated) guard
|
|
40
|
+
# because that call segfaults on Ruby 3.1 while the interrupt is pending.
|
|
41
|
+
def discard_pending_termination
|
|
42
|
+
Thread.handle_interrupt(JobTerminated => :immediate) { nil }
|
|
43
|
+
rescue JobTerminated
|
|
44
|
+
nil
|
|
30
45
|
end
|
|
31
46
|
|
|
32
47
|
def handle_job_terminated(error)
|
|
33
48
|
st_logger.info("Job #{job_id} terminated: #{error.message}")
|
|
34
49
|
SolidQueue::TerminatedExecution.record_termination(self)
|
|
35
|
-
raise
|
|
36
50
|
end
|
|
37
51
|
|
|
38
52
|
def cleanup_termination_row
|
|
@@ -2,13 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
module SolidQueue
|
|
4
4
|
class TerminatedExecution < SolidQueue::Execution
|
|
5
|
+
class NotRetryable < StandardError; end
|
|
6
|
+
|
|
7
|
+
# Copied from the job so retry still works after SolidQueue clears the finished job.
|
|
8
|
+
serialize :arguments, coder: JSON
|
|
9
|
+
|
|
5
10
|
scope :ordered, -> { order(terminated_at: :desc) }
|
|
6
11
|
|
|
12
|
+
# Without the column, `serialize` keeps arguments as a virtual attribute and saves silently drop them.
|
|
13
|
+
def self.log_unless_migrated
|
|
14
|
+
return if table_exists? && column_names.include?('arguments')
|
|
15
|
+
|
|
16
|
+
SolidTerminator.configuration.logger.error(
|
|
17
|
+
'solid_queue_terminated_executions is missing migrations, so terminated jobs cannot be retried. ' \
|
|
18
|
+
'Run `bin/rails generate solid_terminator:update` and migrate.'
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
7
22
|
def self.record_termination(active_job)
|
|
8
23
|
sq_job = SolidQueue::Job.find_by(active_job_id: active_job.job_id)
|
|
9
24
|
return nil unless sq_job
|
|
10
25
|
|
|
11
|
-
|
|
26
|
+
log_unless_migrated
|
|
27
|
+
|
|
28
|
+
create!(job_id: sq_job.id, queue_name: sq_job.queue_name, priority: sq_job.priority,
|
|
29
|
+
arguments: sq_job.arguments, terminated_at: Time.current)
|
|
12
30
|
rescue StandardError => e
|
|
13
31
|
SolidTerminator.configuration.logger.error(
|
|
14
32
|
"Failed to record termination for job #{active_job.job_id}: #{e.class}: #{e.message}"
|
|
@@ -17,7 +35,13 @@ module SolidQueue
|
|
|
17
35
|
end
|
|
18
36
|
|
|
19
37
|
def retry
|
|
20
|
-
|
|
38
|
+
# Rows terminated before 0.2.0 whose job was already cleared got no arguments from the backfill.
|
|
39
|
+
if arguments.nil?
|
|
40
|
+
raise NotRetryable, "Cannot retry terminated execution #{id} (job #{job_id}): its arguments were not " \
|
|
41
|
+
'recorded. It was terminated before solid_terminator 0.2.0 and its job is gone.'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
active_job = ActiveJob::Base.deserialize(arguments)
|
|
21
45
|
transaction do
|
|
22
46
|
destroy!
|
|
23
47
|
active_job.enqueue
|
|
@@ -22,6 +22,21 @@ module SolidTerminator
|
|
|
22
22
|
@mutex.synchronize { @registry[active_job_id] }
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
# Raises under the lock so the job cannot deregister in between and let its pool thread
|
|
26
|
+
# pick up another job, which would then receive the exception instead.
|
|
27
|
+
def raise_in(active_job_id, exception_class, message)
|
|
28
|
+
@mutex.synchronize do
|
|
29
|
+
thread = @registry[active_job_id]
|
|
30
|
+
return :not_registered unless thread
|
|
31
|
+
return :dead unless thread.alive?
|
|
32
|
+
|
|
33
|
+
thread.raise(exception_class, message)
|
|
34
|
+
:raised
|
|
35
|
+
end
|
|
36
|
+
rescue ThreadError
|
|
37
|
+
:dead
|
|
38
|
+
end
|
|
39
|
+
|
|
25
40
|
def active_job_ids
|
|
26
41
|
@mutex.synchronize { @registry.keys.dup }
|
|
27
42
|
end
|
metadata
CHANGED
|
@@ -1,17 +1,45 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solid_terminator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Meszaros Istvan-Abel
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: activejob
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '7.1'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '7.1'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activerecord
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '7.1'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '7.1'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: railties
|
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
|
16
44
|
requirements:
|
|
17
45
|
- - ">="
|
|
@@ -49,11 +77,12 @@ files:
|
|
|
49
77
|
- LICENSE.txt
|
|
50
78
|
- README.md
|
|
51
79
|
- lib/generators/solid_terminator/install_generator.rb
|
|
80
|
+
- lib/generators/solid_terminator/templates/add_arguments_to_solid_queue_terminated_executions.rb
|
|
52
81
|
- lib/generators/solid_terminator/templates/create_solid_queue_terminated_executions.rb
|
|
53
82
|
- lib/generators/solid_terminator/templates/create_solid_queue_terminations.rb
|
|
54
83
|
- lib/generators/solid_terminator/templates/initializer.rb
|
|
84
|
+
- lib/generators/solid_terminator/update_generator.rb
|
|
55
85
|
- lib/solid_terminator.rb
|
|
56
|
-
- lib/solid_terminator/claimed_execution_patch.rb
|
|
57
86
|
- lib/solid_terminator/configuration.rb
|
|
58
87
|
- lib/solid_terminator/engine.rb
|
|
59
88
|
- lib/solid_terminator/job_terminated.rb
|
|
@@ -71,7 +100,7 @@ metadata:
|
|
|
71
100
|
source_code_uri: https://github.com/IstvanMs/solid_terminator
|
|
72
101
|
bug_tracker_uri: https://github.com/IstvanMs/solid_terminator/issues
|
|
73
102
|
changelog_uri: https://github.com/IstvanMs/solid_terminator/blob/main/CHANGELOG.md
|
|
74
|
-
post_install_message:
|
|
103
|
+
post_install_message:
|
|
75
104
|
rdoc_options: []
|
|
76
105
|
require_paths:
|
|
77
106
|
- lib
|
|
@@ -87,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
87
116
|
version: '0'
|
|
88
117
|
requirements: []
|
|
89
118
|
rubygems_version: 3.3.27
|
|
90
|
-
signing_key:
|
|
119
|
+
signing_key:
|
|
91
120
|
specification_version: 4
|
|
92
121
|
summary: Terminate specific in-progress SolidQueue jobs without stopping the worker
|
|
93
122
|
test_files: []
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SolidTerminator
|
|
4
|
-
module ClaimedExecutionPatch
|
|
5
|
-
def perform
|
|
6
|
-
result = execute
|
|
7
|
-
handle_result(result)
|
|
8
|
-
ensure
|
|
9
|
-
unblock_next_job
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
def handle_result(result)
|
|
15
|
-
if result.success?
|
|
16
|
-
finished
|
|
17
|
-
elsif result.error.is_a?(SolidTerminator::JobTerminated)
|
|
18
|
-
finish_terminated
|
|
19
|
-
else
|
|
20
|
-
failed_with(result.error)
|
|
21
|
-
raise result.error
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def finish_terminated
|
|
26
|
-
transaction do
|
|
27
|
-
job.finished!
|
|
28
|
-
destroy!
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|