inst-jobs 2.2.0 → 2.3.3

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: c062c222e731bd490efe572108a508bf78faabee4479f7fe6927a89688d9ef0b
4
- data.tar.gz: 3b1678fc017230e990bc7e8d4e652c23ab59413953ce72a312b13adfa7626193
3
+ metadata.gz: cbfecef485b9884f4504d62b6e4d51345b1c729ae109e5dc619eeb5091dd9d22
4
+ data.tar.gz: e6bd8e6efe0f4a15d77645fe0f4f6b2bd5c2d13be723fba7a42ae72768c834ae
5
5
  SHA512:
6
- metadata.gz: 8c1a722c17c9abc8f5c8a44cb28f6584dc9fb16c1edcccc8df566ad21a5f81af7a54fb70282e2689aee11947dcd96f44ca01dfe542d71c8d3d6b7f145a572ce7
7
- data.tar.gz: 9a7a65c71820d4b04f1e1ac2bf498cf030490a597d075d87d4399a392a7da1bbf50cfb3d5eeb1dea9c357d11e00aabf5e469f062c1fe9cc4b02cc8ed08e1a192
6
+ metadata.gz: 8931e016e05ac54872c3053990402cb85818b53f031eeb0c0118f581a2f3cca73dda2613b99316b1b3bb37fa840b1401b73f02bf307700042f4dc451d2b14067
7
+ data.tar.gz: f301f6495d9854c0e8a53dfd22dd0e8db44994dda66aa22cbf920a7a18adf52170d523578ccd0f5a83971521a556074c270d531d626e216f1cf8af7e7bb0cae5
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddNStrandIndex < ActiveRecord::Migration[5.2]
4
+ disable_ddl_transaction!
5
+
6
+ def change
7
+ add_index :delayed_jobs, [:strand, :next_in_strand, :id],
8
+ name: 'n_strand_index',
9
+ where: 'strand IS NOT NULL',
10
+ algorithm: :concurrently
11
+ end
12
+ end
@@ -13,9 +13,13 @@ end
13
13
  module Delayed
14
14
  module Backend
15
15
  module ActiveRecord
16
+ class AbstractJob < ::ActiveRecord::Base
17
+ self.abstract_class = true
18
+ end
19
+
16
20
  # A job object that is persisted to the database.
17
21
  # Contains the work object as a YAML field.
18
- class Job < ::ActiveRecord::Base
22
+ class Job < AbstractJob
19
23
  include Delayed::Backend::Base
20
24
  self.table_name = :delayed_jobs
21
25
 
@@ -27,7 +31,7 @@ module Delayed
27
31
 
28
32
  class << self
29
33
  def create(attributes, &block)
30
- return super if connection.prepared_statements || Rails.version < '5.2'
34
+ return super if connection.prepared_statements
31
35
 
32
36
  # modified from ActiveRecord::Persistence.create and ActiveRecord::Persistence#_insert_record
33
37
  job = new(attributes, &block)
@@ -37,7 +41,7 @@ module Delayed
37
41
 
38
42
  def single_step_create
39
43
  connection = self.class.connection
40
- return save if connection.prepared_statements || Rails.version < '5.2'
44
+ return save if connection.prepared_statements
41
45
 
42
46
  # a before_save callback that we're skipping
43
47
  initialize_defaults
@@ -66,7 +70,8 @@ module Delayed
66
70
  # > Multiple queries sent in a single PQexec call are processed in a single transaction,
67
71
  # unless there are explicit BEGIN/COMMIT commands included in the query string to divide
68
72
  # it into multiple transactions.
69
- sql = "SELECT pg_advisory_xact_lock(#{connection.quote_table_name('half_md5_as_bigint')}(#{connection.quote(values['strand'])})); #{sql}" if values["strand"]
73
+ # but we don't need to lock when inserting into Delayed::Failed
74
+ sql = "SELECT pg_advisory_xact_lock(#{connection.quote_table_name('half_md5_as_bigint')}(#{connection.quote(values['strand'])})); #{sql}" if values["strand"] && self.class == Job
70
75
  result = connection.execute(sql, "#{self} Create")
71
76
  self.id = result.values.first.first
72
77
  result.clear
@@ -98,7 +103,7 @@ module Delayed
98
103
  # to raise the lock level
99
104
  before_create :lock_strand_on_create
100
105
  def lock_strand_on_create
101
- if strand.present?
106
+ if strand.present? && self.class == Job
102
107
  self.class.connection.execute("SELECT pg_advisory_xact_lock(#{self.class.connection.quote_table_name('half_md5_as_bigint')}(#{self.class.connection.quote(strand)}))")
103
108
  end
104
109
  end
@@ -513,17 +518,6 @@ module Delayed
513
518
  class Failed < Job
514
519
  include Delayed::Backend::Base
515
520
  self.table_name = :failed_jobs
516
- # Rails hasn't completely loaded yet, and setting the table name will cache some stuff
517
- # so reset that cache so that it will load correctly after Rails is all loaded
518
- # It's fixed in Rails 5 to not cache anything when you set the table_name
519
- if Rails.version < '5' && Rails.version >= '4.2'
520
- @arel_engine = nil
521
- @arel_table = nil
522
- end
523
- end
524
- if Rails.version < '5' && Rails.version >= '4.2'
525
- @arel_engine = nil
526
- @arel_table = nil
527
521
  end
528
522
  end
529
523
 
@@ -56,6 +56,12 @@ module Delayed
56
56
  kwargs[:expires_at] = expires_at
57
57
  kwargs[:queue] = queue
58
58
 
59
+ strand_args = 0
60
+ strand_args += 1 if strand
61
+ strand_args += 1 if n_strand
62
+ strand_args += 1 if singleton
63
+ raise ArgumentError, "Only one of strand, n_strand, or singleton can be used" if strand_args > 1
64
+
59
65
  # If two parameters are given to n_strand, the first param is used
60
66
  # as the strand name for looking up the Setting, while the second
61
67
  # param is appended to make a unique set of strands.
@@ -395,13 +395,6 @@ class Job
395
395
  result
396
396
  end
397
397
 
398
- if Rails.version < "4.1"
399
- def changes_applied
400
- @previously_changed = changes
401
- @changed_attributes.clear
402
- end
403
- end
404
-
405
398
  def save!(*a)
406
399
  save(*a) || raise(RecordNotSaved)
407
400
  end
data/lib/delayed/cli.rb CHANGED
@@ -80,7 +80,7 @@ class CLI
80
80
 
81
81
  opts.separator "\n<options>"
82
82
  opts.on("-c", "--config [CONFIG_PATH]", "Use alternate config file (default #{@options[:config_file]})") { |c| @options[:config_file] = c }
83
- opts.on("-p", "--pid", "Use alternate folder for PID files (default #{@options[:pid_folder]})") { |p| @options[:pid_folder] = p }
83
+ opts.on("-p", "--pid [PID_PATH]", "Use alternate folder for PID files (default #{@options[:pid_folder]})") { |p| @options[:pid_folder] = p }
84
84
  opts.on("--no-tail", "Don't tail the logs (only affects non-daemon mode)") { @options[:tail_logs] = false }
85
85
  opts.on("--with-prejudice", "When stopping, interrupt jobs in progress, instead of letting them drain") { @options[:kill] ||= true }
86
86
  opts.on("--with-extreme-prejudice", "When stopping, immediately kill jobs in progress, instead of letting them drain") { @options[:kill] = 9 }
data/lib/delayed/pool.rb CHANGED
@@ -106,6 +106,7 @@ class Pool
106
106
  # db connections with the parent
107
107
  def fork_with_reconnects
108
108
  fork do
109
+ @self_pipe.each(&:close) # sub-processes don't need to wake us up; keep their FDs clean
109
110
  Pool.on_fork.()
110
111
  Delayed::Job.reconnect!
111
112
  yield
@@ -84,7 +84,7 @@ module Delayed
84
84
  def self.worker_config(config_filename = nil)
85
85
  config_filename ||= default_worker_config_name
86
86
  config = YAML.load(ERB.new(File.read(config_filename)).result)
87
- env = defined?(RAILS_ENV) ? RAILS_ENV : ENV['RAILS_ENV'] || 'development'
87
+ env = Rails.env || 'development'
88
88
  config = config[env] || config['default']
89
89
  # Backwards compatibility from when the config was just an array of queues
90
90
  config = { :workers => config } if config.is_a?(Array)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- VERSION = "2.2.0"
4
+ VERSION = "2.3.3"
5
5
  end
@@ -16,6 +16,7 @@ class InProcess
16
16
  end
17
17
 
18
18
  # intentional nops for compatibility w/ parent process
19
+ def init; end
19
20
  def close; end
20
21
  def wake_up; end
21
22
  end
@@ -11,7 +11,10 @@ class ParentProcess
11
11
  def initialize(addrinfo, config: Settings.parent_process)
12
12
  @addrinfo = addrinfo
13
13
  @connect_timeout = config['client_connect_timeout'] || 2
14
- @self_pipe = IO.pipe
14
+ end
15
+
16
+ def init
17
+ @self_pipe ||= IO.pipe
15
18
  end
16
19
 
17
20
  def close
@@ -69,7 +69,6 @@ class Worker
69
69
  @config = options
70
70
  @job_count = 0
71
71
 
72
- @self_pipe = IO.pipe
73
72
  @signal_queue = []
74
73
 
75
74
  app = Rails.application
@@ -120,6 +119,8 @@ class Worker
120
119
  def start
121
120
  logger.info "Starting worker"
122
121
  set_process_name("start:#{Settings.worker_procname_prefix}#{@queue_name}:#{min_priority || 0}:#{max_priority || 'max'}")
122
+ @self_pipe = IO.pipe
123
+ work_queue.init
123
124
 
124
125
  work_thread = Thread.current
125
126
  SIGNALS.each do |sig|
@@ -162,6 +163,9 @@ class Worker
162
163
  signal_processor.kill
163
164
  signal_processor.join
164
165
  end
166
+
167
+ @self_pipe&.each(&:close)
168
+ @self_pipe = nil
165
169
  end
166
170
 
167
171
  def cleanup!
@@ -9,52 +9,49 @@ module Delayed
9
9
  class ConsulHealthCheck < HealthCheck
10
10
  self.type_name = :consul
11
11
 
12
- CONSUL_CONFIG_KEYS = %w{url host port ssl token connect_timeout receive_timeout send_timeout}.map(&:freeze).freeze
12
+ CONSUL_CONFIG_KEYS = %w{url acl_token}.map(&:freeze).freeze
13
13
  DEFAULT_SERVICE_NAME = 'inst-jobs_worker'.freeze
14
- attr_reader :agent_client, :catalog_client
14
+ attr_reader :service_client, :health_client
15
15
 
16
16
  def initialize(*, **)
17
17
  super
18
18
  # Because we don't want the consul client to be a hard dependency we're
19
19
  # only requiring it once it's absolutely needed
20
- require 'imperium'
20
+ require 'diplomat'
21
21
 
22
22
  if config.keys.any? { |k| CONSUL_CONFIG_KEYS.include?(k) }
23
- consul_config = Imperium::Configuration.new.tap do |conf|
23
+ consul_config = Diplomat::Configuration.new.tap do |conf|
24
24
  CONSUL_CONFIG_KEYS.each do |key|
25
25
  conf.send("#{key}=", config[key]) if config[key]
26
26
  end
27
27
  end
28
- @agent_client = Imperium::Agent.new(consul_config)
29
- @catalog_client = Imperium::Catalog.new(consul_config)
28
+ @service_client = Diplomat::Service.new(configuration: consul_config)
29
+ @health_client = Diplomat::Health.new(configuration: consul_config)
30
30
  else
31
- @agent_client = Imperium::Agent.default_client
32
- @catalog_client = Imperium::Catalog.default_client
31
+ @service_client = Diplomat::Service.new
32
+ @health_client = Diplomat::Health.new
33
33
  end
34
34
  end
35
35
 
36
36
  def start
37
- service = Imperium::Service.new({
37
+ @service_client.register({
38
38
  id: worker_name,
39
39
  name: service_name,
40
+ check: check_attributes
40
41
  })
41
- service.add_check(check_attributes)
42
- response = @agent_client.register_service(service)
43
- response.ok?
44
42
  end
45
43
 
46
44
  def stop
47
- response = @agent_client.deregister_service(worker_name)
48
- response.ok? || response.not_found?
45
+ @service_client.deregister(worker_name)
49
46
  end
50
47
 
51
48
  def live_workers
52
- live_nodes = @catalog_client.list_nodes_for_service(service_name)
53
- if live_nodes.ok?
54
- live_nodes.map(&:service_id)
55
- else
56
- raise "Unable to read from Consul catalog: #{live_nodes.content}"
57
- end
49
+ # Filter out critical workers (probably nodes failing their serf health check)
50
+ live_nodes = @health_client.service(service_name, {
51
+ filter: 'not Checks.Status == critical'
52
+ })
53
+
54
+ live_nodes.map { |n| n.Service['ID']}
58
55
  end
59
56
 
60
57
  private
data/lib/delayed_job.rb CHANGED
@@ -18,6 +18,7 @@ require 'rails'
18
18
  require 'active_support/core_ext/module/attribute_accessors'
19
19
  require 'active_record'
20
20
  require 'after_transaction_commit'
21
+ require 'debug_inspector'
21
22
 
22
23
  require 'delayed/core_ext/kernel'
23
24
 
@@ -262,8 +262,6 @@ describe 'Delayed::Backed::ActiveRecord::Job' do
262
262
 
263
263
  context "non-transactional", non_transactional: true do
264
264
  it "creates a stranded job in a single statement" do
265
- skip "Requires Rails 5.2 or greater" unless Rails.version >= '5.2'
266
-
267
265
  allow(Delayed::Job.connection).to receive(:prepared_statements).and_return(false)
268
266
  allow(Delayed::Job.connection).to receive(:execute).with(be_include("pg_advisory_xact_lock"), anything).and_call_original.once
269
267
  allow(Delayed::Job.connection).to receive(:insert).never
@@ -273,8 +271,6 @@ describe 'Delayed::Backed::ActiveRecord::Job' do
273
271
  end
274
272
 
275
273
  it "creates a non-stranded job in a single statement" do
276
- skip "Requires Rails 5.2 or greater" unless Rails.version >= '5.2'
277
-
278
274
  allow(Delayed::Job.connection).to receive(:prepared_statements).and_return(false)
279
275
  call_count = 0
280
276
  allow(Delayed::Job.connection).to receive(:execute).and_wrap_original do |m, (arg1, arg2)|
@@ -286,5 +282,20 @@ describe 'Delayed::Backed::ActiveRecord::Job' do
286
282
  expect(call_count).to eq 1
287
283
  expect(Delayed::Job.find(j.id)).to eq j
288
284
  end
285
+
286
+ it "does not lock a stranded failed job creation" do
287
+ j = create_job(strand: "test1")
288
+ # query for metadata to ensure it's loaded before we start mucking with the connection
289
+ Delayed::Backend::ActiveRecord::Job::Failed.new
290
+
291
+ allow(Delayed::Job.connection).to receive(:prepared_statements).and_return(false)
292
+ allow(Delayed::Job.connection).to receive(:execute).and_wrap_original do |original, *args|
293
+ expect(args.first).not_to include("pg_advisory_xact_lock")
294
+ original.call(*args)
295
+ end
296
+ allow(Delayed::Job.connection).to receive(:insert).never
297
+ j.fail!
298
+ allow(Delayed::Job.connection).to receive(:execute).and_call_original
299
+ end
289
300
  end
290
301
  end
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Delayed::WorkQueue::ParentProcess::Client do
6
- let(:subject) { described_class.new(addrinfo) }
6
+ let(:subject) { described_class.new(addrinfo).tap(&:init) }
7
7
  let(:addrinfo) { double('Addrinfo') }
8
8
  let(:connection) { double('Socket') }
9
9
  let(:job) { Delayed::Job.new(locked_by: "worker_name") }
@@ -1,76 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'imperium'
5
4
 
6
5
  RSpec.describe Delayed::Worker::ConsulHealthCheck do
7
6
  let(:health_check) { Delayed::Worker::ConsulHealthCheck.new(worker_name: 'foobar') }
8
7
 
9
- # can't use a verifying double for the response because the methods we're
10
- # tryig to stub are actually on HTTP::Message
11
- let(:response) { double('Imperium::Response') }
12
- let(:agent_client) { instance_double(Imperium::Agent) }
13
-
14
- before do
15
- allow(Imperium::Agent).to receive(:default_client).and_return(agent_client)
16
- end
17
-
18
8
  describe '#initialize' do
19
- it 'must use the default agent client when the config is mostly empty' do
9
+ it 'must use a default service client when the config is mostly empty' do
20
10
  check = Delayed::Worker::ConsulHealthCheck.new(worker_name: 'foobar')
21
- expect(check.agent_client).to eq Imperium::Agent.default_client
11
+ expect(check.service_client.configuration.url.to_s).to eq 'http://localhost:8500'
22
12
  end
23
13
 
24
- it 'must create a new agent API client when the config has relevant keys set' do
14
+ it 'must create a new service API client when the config has relevant keys set' do
25
15
  check = Delayed::Worker::ConsulHealthCheck.new(worker_name: 'foobar', config: {url: 'http://consul.example.com:8500'})
26
- agent_client = check.agent_client
27
- expect(agent_client).to_not eq Imperium::Agent.default_client
28
- expect(agent_client.config.url.to_s).to eq 'http://consul.example.com:8500'
16
+ service_client = check.service_client
17
+ expect(service_client.configuration.url.to_s).to eq 'http://consul.example.com:8500'
29
18
  end
30
19
  end
31
20
 
32
21
  describe '#start' do
33
22
  it 'must register this process as a service with consul' do
34
- expect(response).to receive(:ok?).and_return(true)
35
- expect(agent_client).to receive(:register_service)
36
- .with(an_instance_of(Imperium::Service))
37
- .and_return(response)
23
+ stub = stub_request(:put, "localhost:8500/v1/agent/service/register")
24
+ .with(body: hash_including({id: 'foobar' }))
25
+
38
26
  health_check.start
27
+
28
+ expect(stub).to have_been_requested
39
29
  end
40
30
 
41
31
 
42
32
  it 'must supply a args style check' do
43
- allow(response).to receive(:ok?).and_return(true)
44
- allow(agent_client).to receive(:register_service) { |service|
45
- check = service.checks.first
46
- expect(check.args).to_not be_nil
47
- response
48
- }
33
+ stub = stub_request(:put, "localhost:8500/v1/agent/service/register")
34
+ .with(body: hash_including({check: WebMock::API.hash_including({args: anything})}))
35
+
49
36
  health_check.start
37
+
38
+ expect(stub).to have_been_requested
50
39
  end
51
40
 
52
41
  it 'must include the docker container id when the docker option is set to true' do
42
+ stub = stub_request(:put, "localhost:8500/v1/agent/service/register")
43
+ .with(body: hash_including({check: WebMock::API.hash_including({docker_container_id: anything})}))
44
+
53
45
  local_health_check = Delayed::Worker::ConsulHealthCheck.new(
54
46
  worker_name: 'foobar',
55
47
  config: {docker: true}
56
48
  )
57
- allow(response).to receive(:ok?).and_return(true)
58
- allow(agent_client).to receive(:register_service) { |service|
59
- check = service.checks.first
60
- expect(check.docker_container_id).to_not be_nil
61
- response
62
- }
63
49
  local_health_check.start
50
+
51
+ expect(stub).to have_been_requested
64
52
  end
65
53
  end
66
54
 
67
55
  describe '#stop' do
68
56
  it 'must deregister the service from consul' do
69
- allow(response).to receive(:ok?).and_return(true)
70
- expect(agent_client).to receive(:deregister_service)
71
- .with(health_check.worker_name)
72
- .and_return(response)
57
+ stub = stub_request(:put, "localhost:8500/v1/agent/service/deregister/foobar")
58
+
73
59
  health_check.stop
60
+ expect(stub).to have_been_requested
74
61
  end
75
62
  end
76
63
  end
@@ -1,7 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gemspec :path=>"../../"
3
+ gemspec :path => "../../"
4
4
 
5
5
  gem "rails", "~> 5.2.0"
6
- gem 'sinatra', "2.0.0.beta2"
7
- gem 'sinatra-contrib', "2.0.0.beta2"
6
+ gem 'sinatra', "~> 2.0"
7
+ gem 'sinatra-contrib', "~> 2.0"
@@ -1,7 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gemspec :path=>"../../"
3
+ gemspec :path => "../../"
4
4
 
5
5
  gem "rails", "~> 6.0.0"
6
- gem 'sinatra', "2.0.0.beta2"
7
- gem 'sinatra-contrib', "2.0.0.beta2"
6
+ gem 'sinatra', "~> 2.0"
7
+ gem 'sinatra-contrib', "~> 2.0"
@@ -0,0 +1,246 @@
1
+ PATH
2
+ remote: ../..
3
+ specs:
4
+ inst-jobs (2.3.1)
5
+ activerecord (>= 5.2)
6
+ activesupport (>= 5.2)
7
+ after_transaction_commit (>= 1.0, < 3)
8
+ debug_inspector (~> 1.0)
9
+ fugit (~> 1.3)
10
+ railties (>= 5.2)
11
+ redis (> 3.0)
12
+ redis-scripting (~> 1.0.1)
13
+
14
+ GEM
15
+ remote: https://rubygems.org/
16
+ specs:
17
+ actioncable (6.0.3.7)
18
+ actionpack (= 6.0.3.7)
19
+ nio4r (~> 2.0)
20
+ websocket-driver (>= 0.6.1)
21
+ actionmailbox (6.0.3.7)
22
+ actionpack (= 6.0.3.7)
23
+ activejob (= 6.0.3.7)
24
+ activerecord (= 6.0.3.7)
25
+ activestorage (= 6.0.3.7)
26
+ activesupport (= 6.0.3.7)
27
+ mail (>= 2.7.1)
28
+ actionmailer (6.0.3.7)
29
+ actionpack (= 6.0.3.7)
30
+ actionview (= 6.0.3.7)
31
+ activejob (= 6.0.3.7)
32
+ mail (~> 2.5, >= 2.5.4)
33
+ rails-dom-testing (~> 2.0)
34
+ actionpack (6.0.3.7)
35
+ actionview (= 6.0.3.7)
36
+ activesupport (= 6.0.3.7)
37
+ rack (~> 2.0, >= 2.0.8)
38
+ rack-test (>= 0.6.3)
39
+ rails-dom-testing (~> 2.0)
40
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
41
+ actiontext (6.0.3.7)
42
+ actionpack (= 6.0.3.7)
43
+ activerecord (= 6.0.3.7)
44
+ activestorage (= 6.0.3.7)
45
+ activesupport (= 6.0.3.7)
46
+ nokogiri (>= 1.8.5)
47
+ actionview (6.0.3.7)
48
+ activesupport (= 6.0.3.7)
49
+ builder (~> 3.1)
50
+ erubi (~> 1.4)
51
+ rails-dom-testing (~> 2.0)
52
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
53
+ activejob (6.0.3.7)
54
+ activesupport (= 6.0.3.7)
55
+ globalid (>= 0.3.6)
56
+ activemodel (6.0.3.7)
57
+ activesupport (= 6.0.3.7)
58
+ activerecord (6.0.3.7)
59
+ activemodel (= 6.0.3.7)
60
+ activesupport (= 6.0.3.7)
61
+ activestorage (6.0.3.7)
62
+ actionpack (= 6.0.3.7)
63
+ activejob (= 6.0.3.7)
64
+ activerecord (= 6.0.3.7)
65
+ marcel (~> 1.0.0)
66
+ activesupport (6.0.3.7)
67
+ concurrent-ruby (~> 1.0, >= 1.0.2)
68
+ i18n (>= 0.7, < 2)
69
+ minitest (~> 5.1)
70
+ tzinfo (~> 1.1)
71
+ zeitwerk (~> 2.2, >= 2.2.2)
72
+ addressable (2.7.0)
73
+ public_suffix (>= 2.0.2, < 5.0)
74
+ after_transaction_commit (2.2.2)
75
+ activerecord (>= 5.2)
76
+ builder (3.2.4)
77
+ bump (0.10.0)
78
+ byebug (11.1.3)
79
+ coderay (1.1.3)
80
+ concurrent-ruby (1.1.9)
81
+ crack (0.4.5)
82
+ rexml
83
+ crass (1.0.6)
84
+ database_cleaner (2.0.1)
85
+ database_cleaner-active_record (~> 2.0.0)
86
+ database_cleaner-active_record (2.0.0)
87
+ activerecord (>= 5.a)
88
+ database_cleaner-core (~> 2.0.0)
89
+ database_cleaner-core (2.0.1)
90
+ debug_inspector (1.1.0)
91
+ deep_merge (1.2.1)
92
+ diff-lcs (1.4.4)
93
+ diplomat (2.5.1)
94
+ deep_merge (~> 1.2)
95
+ faraday (>= 0.9)
96
+ erubi (1.10.0)
97
+ et-orbi (1.2.4)
98
+ tzinfo
99
+ faraday (1.4.1)
100
+ faraday-excon (~> 1.1)
101
+ faraday-net_http (~> 1.0)
102
+ faraday-net_http_persistent (~> 1.1)
103
+ multipart-post (>= 1.2, < 3)
104
+ ruby2_keywords (>= 0.0.4)
105
+ faraday-excon (1.1.0)
106
+ faraday-net_http (1.0.1)
107
+ faraday-net_http_persistent (1.1.0)
108
+ fugit (1.4.5)
109
+ et-orbi (~> 1.1, >= 1.1.8)
110
+ raabro (~> 1.4)
111
+ globalid (0.4.2)
112
+ activesupport (>= 4.2.0)
113
+ hashdiff (1.0.1)
114
+ i18n (1.8.10)
115
+ concurrent-ruby (~> 1.0)
116
+ loofah (2.10.0)
117
+ crass (~> 1.0.2)
118
+ nokogiri (>= 1.5.9)
119
+ mail (2.7.1)
120
+ mini_mime (>= 0.1.1)
121
+ marcel (1.0.1)
122
+ method_source (1.0.0)
123
+ mini_mime (1.1.0)
124
+ minitest (5.14.4)
125
+ multi_json (1.15.0)
126
+ multipart-post (2.1.1)
127
+ mustermann (1.1.1)
128
+ ruby2_keywords (~> 0.0.1)
129
+ nio4r (2.5.7)
130
+ nokogiri (1.11.7-x86_64-darwin)
131
+ racc (~> 1.4)
132
+ pg (1.2.3)
133
+ pry (0.14.1)
134
+ coderay (~> 1.1)
135
+ method_source (~> 1.0)
136
+ public_suffix (4.0.6)
137
+ raabro (1.4.0)
138
+ racc (1.5.2)
139
+ rack (2.2.3)
140
+ rack-protection (2.1.0)
141
+ rack
142
+ rack-test (1.1.0)
143
+ rack (>= 1.0, < 3)
144
+ rails (6.0.3.7)
145
+ actioncable (= 6.0.3.7)
146
+ actionmailbox (= 6.0.3.7)
147
+ actionmailer (= 6.0.3.7)
148
+ actionpack (= 6.0.3.7)
149
+ actiontext (= 6.0.3.7)
150
+ actionview (= 6.0.3.7)
151
+ activejob (= 6.0.3.7)
152
+ activemodel (= 6.0.3.7)
153
+ activerecord (= 6.0.3.7)
154
+ activestorage (= 6.0.3.7)
155
+ activesupport (= 6.0.3.7)
156
+ bundler (>= 1.3.0)
157
+ railties (= 6.0.3.7)
158
+ sprockets-rails (>= 2.0.0)
159
+ rails-dom-testing (2.0.3)
160
+ activesupport (>= 4.2.0)
161
+ nokogiri (>= 1.6)
162
+ rails-html-sanitizer (1.3.0)
163
+ loofah (~> 2.3)
164
+ railties (6.0.3.7)
165
+ actionpack (= 6.0.3.7)
166
+ activesupport (= 6.0.3.7)
167
+ method_source
168
+ rake (>= 0.8.7)
169
+ thor (>= 0.20.3, < 2.0)
170
+ rake (13.0.3)
171
+ redis (4.2.5)
172
+ redis-scripting (1.0.1)
173
+ redis (>= 3.0)
174
+ rexml (3.2.5)
175
+ rspec (3.10.0)
176
+ rspec-core (~> 3.10.0)
177
+ rspec-expectations (~> 3.10.0)
178
+ rspec-mocks (~> 3.10.0)
179
+ rspec-core (3.10.1)
180
+ rspec-support (~> 3.10.0)
181
+ rspec-expectations (3.10.1)
182
+ diff-lcs (>= 1.2.0, < 2.0)
183
+ rspec-support (~> 3.10.0)
184
+ rspec-mocks (3.10.2)
185
+ diff-lcs (>= 1.2.0, < 2.0)
186
+ rspec-support (~> 3.10.0)
187
+ rspec-support (3.10.2)
188
+ ruby2_keywords (0.0.4)
189
+ sinatra (2.1.0)
190
+ mustermann (~> 1.0)
191
+ rack (~> 2.2)
192
+ rack-protection (= 2.1.0)
193
+ tilt (~> 2.0)
194
+ sinatra-contrib (2.1.0)
195
+ multi_json
196
+ mustermann (~> 1.0)
197
+ rack-protection (= 2.1.0)
198
+ sinatra (= 2.1.0)
199
+ tilt (~> 2.0)
200
+ sprockets (4.0.2)
201
+ concurrent-ruby (~> 1.0)
202
+ rack (> 1, < 3)
203
+ sprockets-rails (3.2.2)
204
+ actionpack (>= 4.0)
205
+ activesupport (>= 4.0)
206
+ sprockets (>= 3.0.0)
207
+ thor (1.1.0)
208
+ thread_safe (0.3.6)
209
+ tilt (2.0.10)
210
+ timecop (0.9.4)
211
+ tzinfo (1.2.9)
212
+ thread_safe (~> 0.1)
213
+ webmock (3.13.0)
214
+ addressable (>= 2.3.6)
215
+ crack (>= 0.3.2)
216
+ hashdiff (>= 0.4.0, < 2.0.0)
217
+ websocket-driver (0.7.5)
218
+ websocket-extensions (>= 0.1.0)
219
+ websocket-extensions (0.1.5)
220
+ wwtd (1.4.1)
221
+ zeitwerk (2.4.2)
222
+
223
+ PLATFORMS
224
+ x86_64-darwin-20
225
+
226
+ DEPENDENCIES
227
+ bump
228
+ byebug
229
+ database_cleaner (~> 2.0)
230
+ database_cleaner-active_record (~> 2.0)
231
+ diplomat (~> 2.5.1)
232
+ inst-jobs!
233
+ pg
234
+ pry
235
+ rack-test
236
+ rails (~> 6.0.0)
237
+ rake
238
+ rspec (~> 3.10)
239
+ sinatra (~> 2.0)
240
+ sinatra-contrib (~> 2.0)
241
+ timecop (= 0.9.4)
242
+ webmock
243
+ wwtd (~> 1.4.0)
244
+
245
+ BUNDLED WITH
246
+ 2.2.17
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec :path => "../../"
4
+
5
+ gem "rails", "~> 6.1.0"
6
+ gem 'sinatra', "~> 2.0"
7
+ gem 'sinatra-contrib', "~> 2.0"
@@ -313,6 +313,13 @@ shared_examples_for 'a backend' do
313
313
  expect(second).to eq nil
314
314
  end
315
315
 
316
+ it "complains if you pass more than one strand-based option" do
317
+ expect { create_job(strand: 'a', n_strand: 'b') }.to raise_error(ArgumentError)
318
+ expect { create_job(strand: 'a', singleton: 'b') }.to raise_error(ArgumentError)
319
+ expect { create_job(n_strand: 'a', singleton: 'b') }.to raise_error(ArgumentError)
320
+ expect { create_job(strand: 'a', n_strand: 'b', singleton: 'c') }.to raise_error(ArgumentError)
321
+ end
322
+
316
323
  context 'singleton' do
317
324
  it "should create if there's no jobs on the strand" do
318
325
  @job = create_job(:singleton => 'myjobs')
@@ -21,7 +21,7 @@ shared_examples_for 'Delayed::Worker' do
21
21
 
22
22
  describe "running a job" do
23
23
  it "should not fail when running a job with a % in the name" do
24
- @job = "Some % Name here".delay(ignore_transaction: true).starts_with?("Some % Name")
24
+ @job = "Some % Name here".delay(ignore_transaction: true).start_with?("Some % Name")
25
25
  @worker.perform(@job)
26
26
  end
27
27
  end
data/spec/spec_helper.rb CHANGED
@@ -5,8 +5,9 @@ require 'delayed/testing'
5
5
 
6
6
  require 'database_cleaner'
7
7
  require 'rack/test'
8
- require 'test_after_commit' if ::Rails.version < '5'
9
8
  require 'timecop'
9
+ require 'webmock/rspec'
10
+
10
11
  require 'pry'
11
12
  require 'byebug'
12
13
 
@@ -19,6 +20,7 @@ RSpec.configure do |config|
19
20
  config.before(:suite) do
20
21
  DatabaseCleaner.strategy = :transaction
21
22
  DatabaseCleaner.clean_with(:truncation)
23
+ WebMock.disable_net_connect!
22
24
  end
23
25
 
24
26
  config.before(:each) do |example|
@@ -60,18 +62,8 @@ connection_config = {
60
62
  database: ENV['TEST_DB_DATABASE'],
61
63
  }
62
64
 
63
- if ::Rails.version < '5'
64
- class ActiveRecord::Migration
65
- class << self
66
- def [](_version); self; end
67
- end
68
- end
69
- end
70
-
71
65
  def migrate(file)
72
- if ::Rails.version < '5.2'
73
- ActiveRecord::Migrator.migrate(file)
74
- elsif ::Rails.version >= '6'
66
+ if ::Rails.version >= '6'
75
67
  ActiveRecord::MigrationContext.new(file, ActiveRecord::SchemaMigration).migrate
76
68
  else
77
69
  ActiveRecord::MigrationContext.new(file).migrate
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inst-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-01-06 00:00:00.000000000 Z
12
+ date: 2021-08-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -17,28 +17,28 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '4.2'
20
+ version: '5.2'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: '4.2'
27
+ version: '5.2'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: activesupport
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: '4.2'
34
+ version: '5.2'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: '4.2'
41
+ version: '5.2'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: after_transaction_commit
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -65,14 +65,14 @@ dependencies:
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '4.2'
68
+ version: '5.2'
69
69
  type: :runtime
70
70
  prerelease: false
71
71
  version_requirements: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '4.2'
75
+ version: '5.2'
76
76
  - !ruby/object:Gem::Dependency
77
77
  name: redis
78
78
  requirement: !ruby/object:Gem::Requirement
@@ -121,14 +121,14 @@ dependencies:
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.0.3
124
+ version: '1.0'
125
125
  type: :runtime
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.0.3
131
+ version: '1.0'
132
132
  - !ruby/object:Gem::Dependency
133
133
  name: bump
134
134
  requirement: !ruby/object:Gem::Requirement
@@ -161,44 +161,58 @@ dependencies:
161
161
  name: database_cleaner
162
162
  requirement: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - '='
164
+ - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: 1.6.1
166
+ version: '2.0'
167
167
  type: :development
168
168
  prerelease: false
169
169
  version_requirements: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - '='
171
+ - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: 1.6.1
173
+ version: '2.0'
174
174
  - !ruby/object:Gem::Dependency
175
- name: imperium
175
+ name: database_cleaner-active_record
176
176
  requirement: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - ">="
178
+ - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: 0.5.2
180
+ version: '2.0'
181
181
  type: :development
182
182
  prerelease: false
183
183
  version_requirements: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - ">="
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '2.0'
188
+ - !ruby/object:Gem::Dependency
189
+ name: diplomat
190
+ requirement: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 2.5.1
195
+ type: :development
196
+ prerelease: false
197
+ version_requirements: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
186
200
  - !ruby/object:Gem::Version
187
- version: 0.5.2
201
+ version: 2.5.1
188
202
  - !ruby/object:Gem::Dependency
189
203
  name: pg
190
204
  requirement: !ruby/object:Gem::Requirement
191
205
  requirements:
192
- - - "<"
206
+ - - ">="
193
207
  - !ruby/object:Gem::Version
194
- version: '1.0'
208
+ version: '0'
195
209
  type: :development
196
210
  prerelease: false
197
211
  version_requirements: !ruby/object:Gem::Requirement
198
212
  requirements:
199
- - - "<"
213
+ - - ">="
200
214
  - !ruby/object:Gem::Version
201
- version: '1.0'
215
+ version: '0'
202
216
  - !ruby/object:Gem::Dependency
203
217
  name: pry
204
218
  requirement: !ruby/object:Gem::Requirement
@@ -261,14 +275,14 @@ dependencies:
261
275
  requirements:
262
276
  - - "~>"
263
277
  - !ruby/object:Gem::Version
264
- version: 3.8.0
278
+ version: '3.10'
265
279
  type: :development
266
280
  prerelease: false
267
281
  version_requirements: !ruby/object:Gem::Requirement
268
282
  requirements:
269
283
  - - "~>"
270
284
  - !ruby/object:Gem::Version
271
- version: 3.8.0
285
+ version: '3.10'
272
286
  - !ruby/object:Gem::Dependency
273
287
  name: sinatra
274
288
  requirement: !ruby/object:Gem::Requirement
@@ -303,14 +317,28 @@ dependencies:
303
317
  requirements:
304
318
  - - '='
305
319
  - !ruby/object:Gem::Version
306
- version: 0.7.1
320
+ version: 0.9.4
307
321
  type: :development
308
322
  prerelease: false
309
323
  version_requirements: !ruby/object:Gem::Requirement
310
324
  requirements:
311
325
  - - '='
312
326
  - !ruby/object:Gem::Version
313
- version: 0.7.1
327
+ version: 0.9.4
328
+ - !ruby/object:Gem::Dependency
329
+ name: webmock
330
+ requirement: !ruby/object:Gem::Requirement
331
+ requirements:
332
+ - - ">="
333
+ - !ruby/object:Gem::Version
334
+ version: '0'
335
+ type: :development
336
+ prerelease: false
337
+ version_requirements: !ruby/object:Gem::Requirement
338
+ requirements:
339
+ - - ">="
340
+ - !ruby/object:Gem::Version
341
+ version: '0'
314
342
  - !ruby/object:Gem::Dependency
315
343
  name: wwtd
316
344
  requirement: !ruby/object:Gem::Requirement
@@ -359,6 +387,7 @@ files:
359
387
  - db/migrate/20200330230722_add_id_to_get_delayed_jobs_index.rb
360
388
  - db/migrate/20200824222232_speed_up_max_concurrent_delete_trigger.rb
361
389
  - db/migrate/20200825011002_add_strand_order_override.rb
390
+ - db/migrate/20210809145804_add_n_strand_index.rb
362
391
  - exe/inst_jobs
363
392
  - lib/delayed/backend/active_record.rb
364
393
  - lib/delayed/backend/base.rb
@@ -422,11 +451,10 @@ files:
422
451
  - spec/delayed/worker/consul_health_check_spec.rb
423
452
  - spec/delayed/worker/health_check_spec.rb
424
453
  - spec/delayed/worker_spec.rb
425
- - spec/gemfiles/42.gemfile
426
- - spec/gemfiles/50.gemfile
427
- - spec/gemfiles/51.gemfile
428
454
  - spec/gemfiles/52.gemfile
429
455
  - spec/gemfiles/60.gemfile
456
+ - spec/gemfiles/60.gemfile.lock
457
+ - spec/gemfiles/61.gemfile
430
458
  - spec/migrate/20140924140513_add_story_table.rb
431
459
  - spec/redis_job_spec.rb
432
460
  - spec/sample_jobs.rb
@@ -464,11 +492,10 @@ test_files:
464
492
  - spec/sample_jobs.rb
465
493
  - spec/spec_helper.rb
466
494
  - spec/redis_job_spec.rb
495
+ - spec/gemfiles/60.gemfile.lock
496
+ - spec/gemfiles/61.gemfile
467
497
  - spec/gemfiles/60.gemfile
468
- - spec/gemfiles/42.gemfile
469
498
  - spec/gemfiles/52.gemfile
470
- - spec/gemfiles/50.gemfile
471
- - spec/gemfiles/51.gemfile
472
499
  - spec/shared_jobs_specs.rb
473
500
  - spec/shared/performable_method.rb
474
501
  - spec/shared/testing.rb
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec :path=>"../../"
4
-
5
- gem "rails", "~> 4.2.5"
6
- gem "after_transaction_commit", "<2"
7
- gem 'test_after_commit', '0.4.1'
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec :path=>"../../"
4
-
5
- gem "rails", "~> 5.0.0"
6
- gem 'sinatra', "2.0.0.beta2"
7
- gem 'sinatra-contrib', "2.0.0.beta2"
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec :path=>"../../"
4
-
5
- gem "rails", "~> 5.1.0"
6
- gem 'sinatra', "2.0.0.beta2"
7
- gem 'sinatra-contrib', "2.0.0.beta2"