disqualified 0.3.0 → 0.5.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/README.md +2 -0
- data/app/models/disqualified/base_record.rb +1 -0
- data/app/models/disqualified/record.rb +90 -0
- data/app/models/disqualified/sequence_record.rb +3 -0
- data/disqualified.gemspec +27 -0
- data/lib/disqualified/active_job.rb +4 -0
- data/lib/disqualified/cli.rb +21 -9
- data/lib/disqualified/configuration.rb +21 -0
- data/lib/disqualified/{server_configuration.rb → configuration_structs.rb} +15 -26
- data/lib/disqualified/error.rb +15 -0
- data/lib/disqualified/job.rb +14 -6
- data/lib/disqualified/logging.rb +8 -0
- data/lib/disqualified/main.rb +14 -53
- data/lib/disqualified/pool.rb +4 -5
- data/lib/disqualified/sequence.rb +21 -0
- data/lib/disqualified/version.rb +1 -1
- data/lib/disqualified.rb +6 -1
- data/lib/generators/disqualified/install/USAGE +2 -0
- data/lib/generators/disqualified/install/install_generator.rb +13 -1
- data/lib/generators/disqualified/install/templates/20241119023328_create_disqualified_sequences.rb +17 -0
- metadata +14 -37
- data/config/routes.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbe745886eb9d17ecb6537e23724c48423523695e7c3c1243e166116710d99c0
|
4
|
+
data.tar.gz: f4f9f74ec95f4d3f1f3a8cd2a95907b7d247708676b9c7134c88026813bb7363
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b2d18b8f154938fcb9a6231aa9ba4edd544b06d9a78dba0f7e1def10b12c597d2258f60a5fd7e7ad9704700dab1f3584c96d94a732a26cceba8f4989166d5a7
|
7
|
+
data.tar.gz: 5c648be8f80189afadc35f90a9e6f3c713550626dfc8744629a3867e8b989552c8455f449fef530c9aa13bbeea4be4acbc9654f36a765b48767051af0e731cbb
|
data/README.md
CHANGED
@@ -10,6 +10,8 @@ Note that:
|
|
10
10
|
|
11
11
|
* Disqualified only works with Rails.
|
12
12
|
* Disqualified does not support multiple queues.
|
13
|
+
* Disqualified supports Postgres and MySQL, but it isn't particularly optimized
|
14
|
+
for them.
|
13
15
|
* Each Disqualified process assumes it's the only process running. Running
|
14
16
|
multiple instances of Disqualified should not hurt, but it is not supported.
|
15
17
|
|
@@ -1,3 +1,93 @@
|
|
1
1
|
class Disqualified::Record < Disqualified::BaseRecord
|
2
2
|
self.table_name = "disqualified_jobs"
|
3
|
+
|
4
|
+
belongs_to :disqualified_sequence,
|
5
|
+
class_name: "Disqualified::SequenceRecord",
|
6
|
+
foreign_key: "sequence_uuid",
|
7
|
+
primary_key: "uuid",
|
8
|
+
optional: true
|
9
|
+
|
10
|
+
scope :with_sequence, -> {
|
11
|
+
joins("LEFT OUTER JOIN disqualified_sequences ds ON ds.uuid = sequence_uuid AND ds.current_step = sequence_step")
|
12
|
+
.where("ds.uuid = sequence_uuid OR (ds.uuid IS NULL AND sequence_uuid IS NULL)")
|
13
|
+
}
|
14
|
+
scope :pending, -> { where(finished_at: nil, run_at: (..Time.now), locked_by: nil) }
|
15
|
+
scope :runnable, -> { with_sequence.pending }
|
16
|
+
|
17
|
+
def self.claim_one!(id: nil)
|
18
|
+
run_id = SecureRandom.uuid
|
19
|
+
association =
|
20
|
+
Disqualified::Record
|
21
|
+
.runnable
|
22
|
+
.order(run_at: :asc)
|
23
|
+
.limit(1)
|
24
|
+
|
25
|
+
if id
|
26
|
+
association = association.where(id:)
|
27
|
+
end
|
28
|
+
|
29
|
+
claimed_count = association.update_all(
|
30
|
+
locked_by: run_id,
|
31
|
+
locked_at: Time.now,
|
32
|
+
updated_at: Time.now,
|
33
|
+
attempts: Arel.sql("attempts + 1")
|
34
|
+
)
|
35
|
+
|
36
|
+
raise Disqualified::Error::NoClaimableJob if claimed_count == 0
|
37
|
+
|
38
|
+
Disqualified::Record.find_by!(locked_by: run_id)
|
39
|
+
rescue ActiveRecord::RecordNotFound
|
40
|
+
raise Disqualified::Error::NoClaimableJob
|
41
|
+
end
|
42
|
+
|
43
|
+
def run!
|
44
|
+
record = self.class.claim_one!(id:)
|
45
|
+
begin
|
46
|
+
record.send(:instantiate_handler_and_perform_with_args)
|
47
|
+
rescue => e
|
48
|
+
record.unclaim
|
49
|
+
raise e
|
50
|
+
else
|
51
|
+
record.finish
|
52
|
+
end
|
53
|
+
record
|
54
|
+
end
|
55
|
+
|
56
|
+
def finish
|
57
|
+
transaction do
|
58
|
+
update!(locked_by: nil, locked_at: nil, finished_at: Time.now)
|
59
|
+
if sequence_uuid && sequence_step
|
60
|
+
Disqualified::SequenceRecord
|
61
|
+
.where(uuid: sequence_uuid, current_step: sequence_step)
|
62
|
+
.update_all(
|
63
|
+
current_step: sequence_step + 1,
|
64
|
+
updated_at: Time.now
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def requeue
|
71
|
+
retry_count = attempts - 1
|
72
|
+
sleep = (retry_count**4) + 15 + (rand(10) * (retry_count + 1))
|
73
|
+
unclaim(next_run_at: Time.now + sleep)
|
74
|
+
end
|
75
|
+
|
76
|
+
def unclaim(next_run_at: nil)
|
77
|
+
if next_run_at
|
78
|
+
update!(locked_by: nil, locked_at: nil, run_at: next_run_at)
|
79
|
+
else
|
80
|
+
update!(locked_by: nil, locked_at: nil)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private def instantiate_handler_and_perform_with_args
|
85
|
+
raise Disqualified::Error::JobAlreadyFinished if !finished_at.nil?
|
86
|
+
raise Disqualified::Error::JobNotClaimed if locked_by.nil?
|
87
|
+
|
88
|
+
job_class = handler.constantize
|
89
|
+
parsed_arguments = JSON.parse(arguments)
|
90
|
+
job = job_class.new
|
91
|
+
job.perform(*parsed_arguments)
|
92
|
+
end
|
3
93
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative "lib/disqualified/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "disqualified"
|
5
|
+
spec.version = Disqualified::VERSION
|
6
|
+
spec.authors = ["Zach Ahn"]
|
7
|
+
spec.email = ["engineering@zachahn.com"]
|
8
|
+
spec.homepage = "https://github.com/zachahn/disqualified"
|
9
|
+
spec.summary = "A background job processor tuned for SQLite"
|
10
|
+
spec.license = "LGPL-3.0-only"
|
11
|
+
|
12
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
13
|
+
spec.metadata["source_code_uri"] = "https://github.com/zachahn/disqualified"
|
14
|
+
spec.metadata["changelog_uri"] = "https://github.com/zachahn/disqualified/blob/main/CHANGELOG.md"
|
15
|
+
|
16
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
17
|
+
Dir["{app,exe,lib}/**/*", "*.gemspec", "LICENSE", "README.md"]
|
18
|
+
end
|
19
|
+
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
22
|
+
|
23
|
+
spec.required_ruby_version = ">= 3.1.0"
|
24
|
+
|
25
|
+
spec.add_dependency "rails", ">= 7.0.0"
|
26
|
+
spec.add_dependency "concurrent-ruby", "~> 1.0"
|
27
|
+
end
|
@@ -12,6 +12,10 @@ end
|
|
12
12
|
module ActiveJob
|
13
13
|
module QueueAdapters
|
14
14
|
class DisqualifiedAdapter
|
15
|
+
def enqueue_after_transaction_commit?
|
16
|
+
Disqualified.client_options.enqueue_after_transaction_commit
|
17
|
+
end
|
18
|
+
|
15
19
|
def enqueue(job_data)
|
16
20
|
Disqualified::ActiveJobAdapter.perform_async(job_data.serialize)
|
17
21
|
end
|
data/lib/disqualified/cli.rb
CHANGED
@@ -21,14 +21,20 @@ class Disqualified::CLI
|
|
21
21
|
|
22
22
|
option_parser.parse(@original_argv)
|
23
23
|
|
24
|
-
Disqualified.server_options
|
24
|
+
server_options = Disqualified.server_options
|
25
|
+
delay_range = server_options.delay_range
|
26
|
+
error_hooks = server_options.error_hooks
|
27
|
+
logger = server_options.logger
|
28
|
+
pool_size = server_options.pool_size
|
25
29
|
|
30
|
+
# standard:disable Style/StringLiterals
|
26
31
|
logger.info { ' ____ _ ___ _____ __' }
|
27
32
|
logger.info { ' / __ \(_)________ ___ ______ _/ (_) __(_)__ ____/ /' }
|
28
33
|
logger.info { ' / / / / / ___/ __ `/ / / / __ `/ / / /_/ / _ \/ __ /' }
|
29
34
|
logger.info { ' / /_/ / (__ ) /_/ / /_/ / /_/ / / / __/ / __/ /_/ /' }
|
30
35
|
logger.info { '/_____/_/____/\__, /\__,_/\__,_/_/_/_/ /_/\___/\__,_/' }
|
31
36
|
logger.info { ' /_/' + "v#{Disqualified::VERSION}".rjust(32, " ") }
|
37
|
+
# standard:enable Style/StringLiterals
|
32
38
|
logger.info { Disqualified.server_options.to_s }
|
33
39
|
|
34
40
|
pool = Disqualified::Pool.new(delay_range:, pool_size:, error_hooks:, logger:) do |args|
|
@@ -38,7 +44,7 @@ class Disqualified::CLI
|
|
38
44
|
end
|
39
45
|
pool.run!
|
40
46
|
rescue Interrupt
|
41
|
-
pool
|
47
|
+
pool&.shutdown
|
42
48
|
puts
|
43
49
|
puts "Gracefully quitting..."
|
44
50
|
end
|
@@ -46,19 +52,23 @@ class Disqualified::CLI
|
|
46
52
|
private
|
47
53
|
|
48
54
|
def option_parser
|
49
|
-
@option_parser
|
55
|
+
return @option_parser if instance_variable_defined?(:@option_parser)
|
56
|
+
|
57
|
+
option_parser = OptionParser.new do |opts|
|
50
58
|
opts.banner = "Usage: #{File.basename($0)} [OPTIONS]"
|
51
59
|
|
52
|
-
|
53
|
-
|
60
|
+
server_options = Disqualified.server_options
|
61
|
+
|
62
|
+
opts.on("--delay-low SECONDS", Numeric, "Default: #{server_options.delay_low}") do |value|
|
63
|
+
server_options.delay_low = value
|
54
64
|
end
|
55
65
|
|
56
|
-
opts.on("--delay-high SECONDS", Numeric, "Default: #{
|
57
|
-
|
66
|
+
opts.on("--delay-high SECONDS", Numeric, "Default: #{server_options.delay_high}") do |value|
|
67
|
+
server_options.delay_high = value
|
58
68
|
end
|
59
69
|
|
60
|
-
opts.on("--pool COUNT", Integer, "Default: #{
|
61
|
-
|
70
|
+
opts.on("--pool COUNT", Integer, "Default: #{server_options.pool_size}") do |value|
|
71
|
+
server_options.pool_size = value
|
62
72
|
end
|
63
73
|
|
64
74
|
opts.on("-h", "--help", "Prints this help") do
|
@@ -66,5 +76,7 @@ class Disqualified::CLI
|
|
66
76
|
exit
|
67
77
|
end
|
68
78
|
end
|
79
|
+
|
80
|
+
@option_parser ||= option_parser
|
69
81
|
end
|
70
82
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Disqualified
|
2
|
+
@client_options = ClientConfiguration.new
|
3
|
+
|
4
|
+
class << self
|
5
|
+
attr_accessor :client_options
|
6
|
+
|
7
|
+
attr_accessor :server_options
|
8
|
+
|
9
|
+
def configure_client(&block)
|
10
|
+
block.call(client_options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# While client options are always run, server options only run in the "disqualified" process
|
14
|
+
|
15
|
+
def configure_server(&block)
|
16
|
+
if server_options
|
17
|
+
block.call(server_options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,30 +1,31 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
class Disqualified::ClientConfiguration
|
2
|
+
def initialize
|
3
|
+
@enqueue_after_transaction_commit = false
|
4
4
|
end
|
5
5
|
|
6
|
-
|
7
|
-
if server_options
|
8
|
-
yield server_options
|
9
|
-
end
|
10
|
-
end
|
6
|
+
attr_accessor :enqueue_after_transaction_commit
|
11
7
|
end
|
12
8
|
|
13
9
|
class Disqualified::ServerConfiguration
|
14
10
|
def initialize
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
@delay_high = 5.0
|
12
|
+
@delay_low = 1.0
|
13
|
+
@logger = Rails.logger
|
14
|
+
@pool_size = 5
|
15
|
+
@pwd = Dir.pwd
|
16
|
+
@error_hooks = []
|
21
17
|
end
|
22
18
|
|
23
19
|
attr_accessor :delay_high
|
20
|
+
|
24
21
|
attr_accessor :delay_low
|
22
|
+
|
25
23
|
attr_accessor :error_hooks
|
24
|
+
|
26
25
|
attr_accessor :logger
|
26
|
+
|
27
27
|
attr_accessor :pool_size
|
28
|
+
|
28
29
|
attr_accessor :pwd
|
29
30
|
|
30
31
|
private :error_hooks=
|
@@ -37,18 +38,6 @@ class Disqualified::ServerConfiguration
|
|
37
38
|
error_hooks.push(block)
|
38
39
|
end
|
39
40
|
|
40
|
-
def to_h
|
41
|
-
{
|
42
|
-
delay_high:,
|
43
|
-
delay_low:,
|
44
|
-
delay_range:,
|
45
|
-
error_hooks:,
|
46
|
-
logger:,
|
47
|
-
pool_size:,
|
48
|
-
pwd:
|
49
|
-
}
|
50
|
-
end
|
51
|
-
|
52
41
|
def to_s
|
53
42
|
"{ delay: #{delay_range}, pool_size: #{pool_size}, error_hooks_size: #{error_hooks.size} }"
|
54
43
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Disqualified
|
2
|
+
module Error
|
3
|
+
class DisqualifiedError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class JobAlreadyFinished < DisqualifiedError
|
7
|
+
end
|
8
|
+
|
9
|
+
class JobNotClaimed < DisqualifiedError
|
10
|
+
end
|
11
|
+
|
12
|
+
class NoClaimableJob < DisqualifiedError
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/disqualified/job.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
module Disqualified::Job
|
2
|
-
def self.included(base)
|
3
|
-
base.extend ClassMethods
|
4
|
-
end
|
5
|
-
|
6
2
|
module ClassMethods
|
7
3
|
def perform_at(the_time, *args)
|
8
|
-
Disqualified::
|
4
|
+
if Thread.current[Disqualified::Sequence::UUID]
|
5
|
+
Thread.current[Disqualified::Sequence::COUNT] += 1
|
6
|
+
sequence_uuid = Thread.current[Disqualified::Sequence::UUID]
|
7
|
+
sequence_step = Thread.current[Disqualified::Sequence::COUNT]
|
8
|
+
end
|
9
|
+
|
10
|
+
Disqualified::Record.create!(
|
9
11
|
handler: name,
|
10
12
|
arguments: JSON.dump(args),
|
11
13
|
queue: "default",
|
12
|
-
run_at: the_time
|
14
|
+
run_at: the_time,
|
15
|
+
sequence_uuid:,
|
16
|
+
sequence_step:
|
13
17
|
)
|
14
18
|
end
|
15
19
|
|
@@ -21,4 +25,8 @@ module Disqualified::Job
|
|
21
25
|
perform_at(Time.now + delay, *args)
|
22
26
|
end
|
23
27
|
end
|
28
|
+
|
29
|
+
def self.included(other)
|
30
|
+
other.extend(ClassMethods)
|
31
|
+
end
|
24
32
|
end
|
data/lib/disqualified/logging.rb
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
module Disqualified::Logging
|
2
|
+
ERROR_CONTEXT_TYPE = T.type_alias do
|
3
|
+
T::Hash[T.untyped, T.untyped]
|
4
|
+
end
|
5
|
+
|
6
|
+
ERROR_HOOK_TYPE = T.type_alias do
|
7
|
+
T.proc.params(arg0: Exception, arg1: ERROR_CONTEXT_TYPE).void
|
8
|
+
end
|
9
|
+
|
2
10
|
module_function
|
3
11
|
|
4
12
|
def format_log(*parts)
|
data/lib/disqualified/main.rb
CHANGED
@@ -7,61 +7,22 @@ class Disqualified::Main
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def call
|
10
|
-
run_id = SecureRandom.uuid
|
11
|
-
|
12
10
|
Rails.application.reloader.wrap do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@logger.
|
22
|
-
|
23
|
-
next if claimed_count == 0
|
24
|
-
|
25
|
-
# Find the job that we claimed; quit early if none was claimed
|
26
|
-
job = Disqualified::Record.find_by!(locked_by: run_id)
|
27
|
-
|
28
|
-
begin
|
29
|
-
# Deserialize job
|
30
|
-
handler_class = job.handler.constantize
|
31
|
-
arguments = JSON.parse(job.arguments)
|
32
|
-
|
33
|
-
@logger.info do
|
34
|
-
format_log("Disqualified::Main#call", "Runner #{run_id}" "Running `#{job.handler}'")
|
35
|
-
end
|
36
|
-
|
37
|
-
# Run the job
|
38
|
-
handler = handler_class.new
|
39
|
-
handler.perform(*arguments)
|
40
|
-
|
41
|
-
finish(job)
|
42
|
-
|
43
|
-
@logger.info do
|
44
|
-
format_log("Disqualified::Main#call", "Runner #{run_id}", "Done")
|
45
|
-
end
|
46
|
-
rescue => e
|
47
|
-
handle_error(@error_hooks, e, {record: job.attributes})
|
48
|
-
@logger.error { format_log("Disqualified::Main#run", "Runner #{run_id}", "Rescued Record ##{job&.id}") }
|
49
|
-
requeue(job)
|
11
|
+
record = Disqualified::Record.claim_one!
|
12
|
+
run_id = record.locked_by
|
13
|
+
record.send(:instantiate_handler_and_perform_with_args)
|
14
|
+
record.finish
|
15
|
+
@logger.info do
|
16
|
+
format_log("Disqualified::Main#call", "Runner #{run_id}", "Done")
|
17
|
+
end
|
18
|
+
rescue Disqualified::Error::NoClaimableJob
|
19
|
+
@logger.warn do
|
20
|
+
format_log("Disqualified::Main#call", "No claimable jobs")
|
50
21
|
end
|
22
|
+
rescue => e
|
23
|
+
handle_error(@error_hooks, e, {record: record.attributes})
|
24
|
+
@logger.error { format_log("Disqualified::Main#run", "Runner #{run_id}", "Rescued Record ##{record.id}") }
|
25
|
+
record.requeue
|
51
26
|
end
|
52
27
|
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def finish(job)
|
57
|
-
job.update!(locked_by: nil, locked_at: nil, finished_at: Time.now)
|
58
|
-
end
|
59
|
-
|
60
|
-
def requeue(job)
|
61
|
-
# Formula from the Sidekiq wiki
|
62
|
-
retry_count = job.attempts - 1
|
63
|
-
sleep = (retry_count**4) + 15 + (rand(10) * (retry_count + 1))
|
64
|
-
@logger.debug { format_log("Disqualified::Main#requeue", "Sleeping job for #{sleep} seconds") }
|
65
|
-
job.update!(locked_by: nil, locked_at: nil, run_at: Time.now + sleep)
|
66
|
-
end
|
67
28
|
end
|
data/lib/disqualified/pool.rb
CHANGED
@@ -44,11 +44,10 @@ class Disqualified::Pool
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def pool
|
47
|
-
@pool ||=
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
47
|
+
@pool ||= @pool_size.times.map do |promise_index|
|
48
|
+
repeat(promise_index:)
|
49
|
+
&.run
|
50
|
+
end
|
52
51
|
end
|
53
52
|
|
54
53
|
def repeat(promise_index:)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Disqualified::Sequence
|
2
|
+
UUID = :disqualified_sequence_uuid
|
3
|
+
COUNT = :disqualified_sequence_count
|
4
|
+
|
5
|
+
def self.queue(description: nil, &block)
|
6
|
+
Disqualified::SequenceRecord.transaction do
|
7
|
+
Thread.current[UUID] = SecureRandom.uuid
|
8
|
+
Thread.current[COUNT] = 0
|
9
|
+
yield
|
10
|
+
Disqualified::SequenceRecord.create!(
|
11
|
+
uuid: Thread.current[UUID],
|
12
|
+
current_step: 1,
|
13
|
+
final_step: Thread.current[COUNT],
|
14
|
+
description:
|
15
|
+
)
|
16
|
+
end
|
17
|
+
ensure
|
18
|
+
Thread.current[UUID] = nil
|
19
|
+
Thread.current[COUNT] = nil
|
20
|
+
end
|
21
|
+
end
|
data/lib/disqualified/version.rb
CHANGED
data/lib/disqualified.rb
CHANGED
@@ -5,12 +5,17 @@ require "optparse"
|
|
5
5
|
|
6
6
|
require "concurrent"
|
7
7
|
require "rails"
|
8
|
+
require "sorbet-runtime"
|
8
9
|
|
10
|
+
require_relative "disqualified/error"
|
9
11
|
require_relative "disqualified/logging"
|
10
12
|
|
13
|
+
require_relative "disqualified/configuration_structs"
|
14
|
+
|
15
|
+
require_relative "disqualified/configuration"
|
11
16
|
require_relative "disqualified/engine"
|
12
17
|
require_relative "disqualified/job"
|
13
18
|
require_relative "disqualified/main"
|
14
19
|
require_relative "disqualified/pool"
|
15
|
-
require_relative "disqualified/
|
20
|
+
require_relative "disqualified/sequence"
|
16
21
|
require_relative "disqualified/version"
|
@@ -1,8 +1,20 @@
|
|
1
|
+
require "rails/generators/active_record"
|
2
|
+
|
1
3
|
class Disqualified::InstallGenerator < Rails::Generators::Base
|
4
|
+
include ActiveRecord::Generators::Migration
|
5
|
+
|
2
6
|
source_root File.expand_path("templates", __dir__)
|
3
7
|
|
8
|
+
class_option :database,
|
9
|
+
type: :string,
|
10
|
+
aliases: %i[--db],
|
11
|
+
desc: "The database for your migration. By default, the current environment's primary database is used."
|
12
|
+
|
4
13
|
def copy_migration_file
|
5
14
|
basename = "20220703062536_create_disqualified_jobs.rb"
|
6
|
-
copy_file
|
15
|
+
copy_file(basename, File.join(db_migrate_path, basename))
|
16
|
+
|
17
|
+
basename = "20241119023328_create_disqualified_sequences.rb"
|
18
|
+
copy_file(basename, File.join(db_migrate_path, basename))
|
7
19
|
end
|
8
20
|
end
|
data/lib/generators/disqualified/install/templates/20241119023328_create_disqualified_sequences.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateDisqualifiedSequences < ActiveRecord::Migration[7.2]
|
2
|
+
def change
|
3
|
+
create_table :disqualified_sequences do |t|
|
4
|
+
t.text :uuid, null: false
|
5
|
+
t.integer :current_step, null: false
|
6
|
+
t.integer :final_step, null: false
|
7
|
+
t.text :description
|
8
|
+
t.timestamps
|
9
|
+
|
10
|
+
t.index :uuid, unique: true
|
11
|
+
end
|
12
|
+
|
13
|
+
add_column :disqualified_jobs, :sequence_uuid, :text
|
14
|
+
add_column :disqualified_jobs, :sequence_step, :integer
|
15
|
+
add_index :disqualified_jobs, [:sequence_uuid, :sequence_step], unique: true
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: disqualified
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zach Ahn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -28,44 +28,16 @@ dependencies:
|
|
28
28
|
name: concurrent-ruby
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: mocktail
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: standard
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
38
|
+
- - "~>"
|
67
39
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
40
|
+
version: '1.0'
|
69
41
|
description:
|
70
42
|
email:
|
71
43
|
- engineering@zachahn.com
|
@@ -78,21 +50,26 @@ files:
|
|
78
50
|
- README.md
|
79
51
|
- app/models/disqualified/base_record.rb
|
80
52
|
- app/models/disqualified/record.rb
|
81
|
-
-
|
53
|
+
- app/models/disqualified/sequence_record.rb
|
54
|
+
- disqualified.gemspec
|
82
55
|
- exe/disqualified
|
83
56
|
- lib/disqualified.rb
|
84
57
|
- lib/disqualified/active_job.rb
|
85
58
|
- lib/disqualified/cli.rb
|
59
|
+
- lib/disqualified/configuration.rb
|
60
|
+
- lib/disqualified/configuration_structs.rb
|
86
61
|
- lib/disqualified/engine.rb
|
62
|
+
- lib/disqualified/error.rb
|
87
63
|
- lib/disqualified/job.rb
|
88
64
|
- lib/disqualified/logging.rb
|
89
65
|
- lib/disqualified/main.rb
|
90
66
|
- lib/disqualified/pool.rb
|
91
|
-
- lib/disqualified/
|
67
|
+
- lib/disqualified/sequence.rb
|
92
68
|
- lib/disqualified/version.rb
|
93
69
|
- lib/generators/disqualified/install/USAGE
|
94
70
|
- lib/generators/disqualified/install/install_generator.rb
|
95
71
|
- lib/generators/disqualified/install/templates/20220703062536_create_disqualified_jobs.rb
|
72
|
+
- lib/generators/disqualified/install/templates/20241119023328_create_disqualified_sequences.rb
|
96
73
|
homepage: https://github.com/zachahn/disqualified
|
97
74
|
licenses:
|
98
75
|
- LGPL-3.0-only
|
@@ -115,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
92
|
- !ruby/object:Gem::Version
|
116
93
|
version: '0'
|
117
94
|
requirements: []
|
118
|
-
rubygems_version: 3.
|
95
|
+
rubygems_version: 3.5.11
|
119
96
|
signing_key:
|
120
97
|
specification_version: 4
|
121
98
|
summary: A background job processor tuned for SQLite
|
data/config/routes.rb
DELETED