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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34ac6d57608468421c25cb83e842ce8cadc028b922e4437e39580ba8f8009106
4
- data.tar.gz: 8bf4b146c66caaeae5a322c013b9be859436e17940f6747643289f76edb84abc
3
+ metadata.gz: fbe745886eb9d17ecb6537e23724c48423523695e7c3c1243e166116710d99c0
4
+ data.tar.gz: f4f9f74ec95f4d3f1f3a8cd2a95907b7d247708676b9c7134c88026813bb7363
5
5
  SHA512:
6
- metadata.gz: 2c5c1472c10779a1f55aa88b946801e3ef7ba725538bda4c415572ca8f103c6df81e709399455cc901b419dec15534714fde445d09503f495d9660c7c4bf7f16
7
- data.tar.gz: 6eda9531c46d5002efd09c6784551cd2e1cefc7b912143010a92f97ce87db1d478bbcc05c507d22dcb1272f63d97afca57f9d4a758cd67185e86f4588fb7e876
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,2 +1,3 @@
1
1
  class Disqualified::BaseRecord < ActiveRecord::Base
2
+ self.abstract_class = true
2
3
  end
@@ -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,3 @@
1
+ class Disqualified::SequenceRecord < Disqualified::BaseRecord
2
+ self.table_name = "disqualified_sequences"
3
+ 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
@@ -21,14 +21,20 @@ class Disqualified::CLI
21
21
 
22
22
  option_parser.parse(@original_argv)
23
23
 
24
- Disqualified.server_options.to_h => {delay_range:, error_hooks:, logger:, pool_size:}
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.shutdown
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 ||= OptionParser.new do |opts|
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
- opts.on("--delay-low SECONDS", Numeric, "Default: #{Disqualified.server_options.delay_low}") do |value|
53
- Disqualified.server_options.delay_low = value
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: #{Disqualified.server_options.delay_high}") do |value|
57
- Disqualified.server_options.delay_high = value
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: #{Disqualified.server_options.pool_size}") do |value|
61
- Disqualified.server_options.pool_size = value
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
- module Disqualified
2
- class << self
3
- attr_accessor :server_options
1
+ class Disqualified::ClientConfiguration
2
+ def initialize
3
+ @enqueue_after_transaction_commit = false
4
4
  end
5
5
 
6
- def self.configure_server
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
- self.delay_high = 5.0
16
- self.delay_low = 1.0
17
- self.logger = Rails.logger
18
- self.pool_size = 5
19
- self.pwd = Dir.pwd
20
- self.error_hooks = []
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
@@ -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::Record.create(
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
@@ -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)
@@ -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
- # Claim a job
14
- claimed_count =
15
- Disqualified::Record
16
- .where(finished_at: nil, run_at: (..Time.now), locked_by: nil)
17
- .order(run_at: :asc)
18
- .limit(1)
19
- .update_all(locked_by: run_id, locked_at: Time.now, updated_at: Time.now, attempts: Arel.sql("attempts + 1"))
20
-
21
- @logger.debug { format_log("Disqualified::Main#call", "Runner #{run_id}", "Claimed #{claimed_count}") }
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
@@ -44,11 +44,10 @@ class Disqualified::Pool
44
44
  end
45
45
 
46
46
  def pool
47
- @pool ||=
48
- @pool_size.times.map do |promise_index|
49
- repeat(promise_index:)
50
- .run
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
@@ -1,3 +1,3 @@
1
1
  module Disqualified
2
- VERSION = "0.3.0"
2
+ VERSION = "0.5.0"
3
3
  end
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/server_configuration"
20
+ require_relative "disqualified/sequence"
16
21
  require_relative "disqualified/version"
@@ -3,6 +3,8 @@ Description:
3
3
 
4
4
  Example:
5
5
  bin/rails generate disqualified:install
6
+ bin/rails generate disqualified:install --database primary
7
+ bin/rails g disqualified:install --db=animals
6
8
 
7
9
  This will create:
8
10
  db/migrate/20220703062536_create_disqualified_jobs.rb
@@ -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 basename, "db/migrate/#{basename}"
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
@@ -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.3.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: 2023-04-16 00:00:00.000000000 Z
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
- - config/routes.rb
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/server_configuration.rb
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.4.7
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
@@ -1,2 +0,0 @@
1
- Rails.application.routes.draw do
2
- end