inst-jobs 3.1.7 → 3.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0475c3b076cb2d06a380ab5439899071d7b242f0b984efc656c07cdac42a30ef
4
- data.tar.gz: 6b327fe5fa9e90ff3e0a9cc6fbbf3bf141fac324999c7b3fe4b86c60196ddab0
3
+ metadata.gz: 4b84071f5e26623586c13f855f5ce616786a61fa18ebae0a4640cfd48ab2a63c
4
+ data.tar.gz: c2c386ac0864c1ac08173eb4960ccdf1f7b89184799c59f7d1b427b4330c548d
5
5
  SHA512:
6
- metadata.gz: fc255ab122c9744ba5222125898d43d12e668d091c5ad7f034693e5ce6d224be21c107caf67261d3bdef03b55f481baa4d0d3912e3c9bff8e1039d8ff12f3f35
7
- data.tar.gz: 6a7d73a994637c0241d54da38e98a8c25008345622b9410a867da603740c6eb8133e7bb1d36e8dd62d479148e7bf43bc5e0ea0f1a59f63dd1f0b8a7763467e19
6
+ metadata.gz: 898a6eb496ec26e653ba3a360cd1e820aaba1a04b3768a265976b5d3ed9150e38795f25fdb1adfb89c69f930ec6bb92d2388e36685685abac0209c1e534e2f36
7
+ data.tar.gz: 26c8af5d1a05624a0ffd161f8d49fa5c81a205f974849577a0d7fa9c84735c48e0269d7078a038fb2e9865aeae294378b12656c0d5359c3d80bbc31429acf0b7
@@ -9,7 +9,8 @@ class AddIdToGetDelayedJobsIndex < ActiveRecord::Migration[4.2]
9
9
 
10
10
  def up
11
11
  rename_index :delayed_jobs, "get_delayed_jobs_index", "get_delayed_jobs_index_old"
12
- add_index :delayed_jobs, %i[queue priority run_at id],
12
+ add_index :delayed_jobs,
13
+ %i[queue priority run_at id],
13
14
  algorithm: :concurrently,
14
15
  where: "locked_at IS NULL AND next_in_strand",
15
16
  name: "get_delayed_jobs_index"
@@ -18,7 +19,8 @@ class AddIdToGetDelayedJobsIndex < ActiveRecord::Migration[4.2]
18
19
 
19
20
  def down
20
21
  rename_index :delayed_jobs, "get_delayed_jobs_index", "get_delayed_jobs_index_old"
21
- add_index :delayed_jobs, %i[priority run_at queue],
22
+ add_index :delayed_jobs,
23
+ %i[priority run_at queue],
22
24
  algorithm: :concurrently,
23
25
  where: "locked_at IS NULL AND next_in_strand",
24
26
  name: "get_delayed_jobs_index"
@@ -10,7 +10,8 @@ class AddStrandOrderOverride < ActiveRecord::Migration[4.2]
10
10
  def up
11
11
  add_column :delayed_jobs, :strand_order_override, :integer, default: 0, null: false
12
12
  add_column :failed_jobs, :strand_order_override, :integer, default: 0, null: false
13
- add_index :delayed_jobs, %i[strand strand_order_override id],
13
+ add_index :delayed_jobs,
14
+ %i[strand strand_order_override id],
14
15
  algorithm: :concurrently,
15
16
  where: "strand IS NOT NULL",
16
17
  name: "next_in_strand_index"
@@ -4,7 +4,8 @@ class AddNStrandIndex < ActiveRecord::Migration[5.2]
4
4
  disable_ddl_transaction!
5
5
 
6
6
  def change
7
- add_index :delayed_jobs, %i[strand next_in_strand id],
7
+ add_index :delayed_jobs,
8
+ %i[strand next_in_strand id],
8
9
  name: "n_strand_index",
9
10
  where: "strand IS NOT NULL",
10
11
  algorithm: :concurrently
@@ -115,7 +115,7 @@ module Delayed
115
115
  # but we don't need to lock when inserting into Delayed::Failed
116
116
  if values["strand"] && instance_of?(Job)
117
117
  fn_name = connection.quote_table_name("half_md5_as_bigint")
118
- quoted_strand = connection.quote(Rails.version < "7.0" ? values["strand"] : values["strand"].value)
118
+ quoted_strand = connection.quote((Rails.version < "7.0") ? values["strand"] : values["strand"].value)
119
119
  sql = "SELECT pg_advisory_xact_lock(#{fn_name}(#{quoted_strand})); #{sql}"
120
120
  end
121
121
  result = connection.execute(sql, "#{self.class} Create")
@@ -253,7 +253,7 @@ module Delayed
253
253
  offset = 0,
254
254
  query = nil)
255
255
  scope = scope_for_flavor(flavor, query)
256
- order = flavor.to_s == "future" ? "run_at" : "id desc"
256
+ order = (flavor.to_s == "future") ? "run_at" : "id desc"
257
257
  scope.order(order).limit(limit).offset(offset).to_a
258
258
  end
259
259
 
@@ -607,7 +607,12 @@ module Delayed
607
607
  end
608
608
 
609
609
  def requeue!
610
- attrs = attributes.except("id", "last_error", "locked_at", "failed_at", "locked_by", "original_job_id",
610
+ attrs = attributes.except("id",
611
+ "last_error",
612
+ "locked_at",
613
+ "failed_at",
614
+ "locked_by",
615
+ "original_job_id",
611
616
  "requeued_job_id")
612
617
  self.class.transaction do
613
618
  job = nil
@@ -62,6 +62,9 @@ module Delayed
62
62
  kwargs[:singleton] = singleton
63
63
 
64
64
  raise ArgumentError, "Only one of strand or n_strand can be used" if strand && n_strand
65
+ if (strand || n_strand) && run_at && run_at > Job.db_time_now + Settings.stranded_run_at_grace_period
66
+ raise ArgumentError, "Do not use run_at with strand; you may inadvertently clog the strand"
67
+ end
65
68
 
66
69
  # If two parameters are given to n_strand, the first param is used
67
70
  # as the strand name for looking up the Setting, while the second
@@ -113,7 +116,7 @@ module Delayed
113
116
  # effectively balancing the load during queueing
114
117
  # overwritten in ActiveRecord::Job to use triggers to balance at run time
115
118
  def n_strand_options(strand_name, num_strands)
116
- strand_num = num_strands > 1 ? rand(num_strands) + 1 : 1
119
+ strand_num = (num_strands > 1) ? rand(num_strands) + 1 : 1
117
120
  strand_name += ":#{strand_num}" if strand_num > 1
118
121
  { strand: strand_name }
119
122
  end
@@ -214,7 +217,7 @@ module Delayed
214
217
  def failed?
215
218
  failed_at
216
219
  end
217
- alias failed failed?
220
+ alias_method :failed, :failed?
218
221
 
219
222
  def expired?
220
223
  expires_at && (self.class.db_time_now >= expires_at)
data/lib/delayed/cli.rb CHANGED
@@ -49,7 +49,7 @@ module Delayed
49
49
  daemon.daemonize!
50
50
  start
51
51
  when nil
52
- puts option_parser.to_s
52
+ puts option_parser.help
53
53
  else
54
54
  raise("Unknown command: #{command.inspect}")
55
55
  end
@@ -82,7 +82,8 @@ module Delayed
82
82
  opts.on("-c", "--config [CONFIG_PATH]", "Use alternate config file (default #{@options[:config_file]})") do |c|
83
83
  @options[:config_file] = c
84
84
  end
85
- opts.on("-p", "--pid [PID_PATH]",
85
+ opts.on("-p",
86
+ "--pid [PID_PATH]",
86
87
  "Use alternate folder for PID files (default #{@options[:pid_folder]})") do |p|
87
88
  @options[:pid_folder] = p
88
89
  end
@@ -46,7 +46,7 @@ module Delayed
46
46
  missing_callback(event) unless @callbacks.key?(event)
47
47
 
48
48
  unless EVENTS[event].size == args.size
49
- raise ArgumentError, "Callback #{event} expects #{EVENTS[event].size} parameter(s): #{EVENTS[event].join(', ')}"
49
+ raise ArgumentError, "Callback #{event} expects #{EVENTS[event].size} parameter(s): #{EVENTS[event].join(", ")}"
50
50
  end
51
51
 
52
52
  @callbacks[event].execute(*args, &block)
@@ -5,8 +5,8 @@ module Delayed
5
5
  def run
6
6
  if Rails.logger.respond_to?(:log_path)
7
7
  log_path = Rails.logger.log_path
8
- elsif Rails.logger.instance_variable_get("@logdev").try(:instance_variable_get, "@dev").try(:path)
9
- log_path = Rails.logger.instance_variable_get("@logdev").instance_variable_get("@dev").path
8
+ elsif Rails.logger.instance_variable_get(:@logdev).try(:instance_variable_get, "@dev").try(:path)
9
+ log_path = Rails.logger.instance_variable_get(:@logdev).instance_variable_get(:@dev).path
10
10
  else
11
11
  return
12
12
  end
@@ -19,7 +19,7 @@ module Delayed
19
19
  @object.protected_methods.exclude?(method) &&
20
20
  @object.private_methods.exclude?(method)
21
21
 
22
- sender_is_object = @sender == @object
22
+ sender_is_object = @sender.equal?(@object)
23
23
  sender_is_class = @sender.is_a?(@object.class)
24
24
 
25
25
  # even if the call is async, if the call is _going_ to generate an error, we make it synchronous
@@ -54,8 +54,10 @@ module Delayed
54
54
 
55
55
  if ::Delayed::Job != ::Delayed::Backend::ActiveRecord::Job || connection != ::Delayed::Job.connection
56
56
  connection.after_transaction_commit do
57
- ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object, method,
58
- args: args, kwargs: kwargs,
57
+ ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object,
58
+ method,
59
+ args: args,
60
+ kwargs: kwargs,
59
61
  on_failure: on_failure,
60
62
  on_permanent_failure: on_permanent_failure,
61
63
  sender: @sender),
@@ -65,7 +67,8 @@ module Delayed
65
67
  end
66
68
  end
67
69
 
68
- result = ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object, method,
70
+ result = ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object,
71
+ method,
69
72
  args: args,
70
73
  kwargs: kwargs,
71
74
  on_failure: on_failure,
@@ -1,7 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- PerformableMethod = Struct.new(:object, :method, :args, :kwargs, :fail_cb, :permanent_fail_cb, :sender) do # rubocop:disable Lint/StructNewOverride
4
+ PerformableMethod = Struct.new(:object,
5
+ :method, # rubocop:disable Lint/StructNewOverride
6
+ :args,
7
+ :kwargs,
8
+ :fail_cb,
9
+ :permanent_fail_cb,
10
+ :sender,
11
+ :sender_is_object,
12
+ :sender_is_class) do
5
13
  def initialize(object, method, args: [], kwargs: {}, on_failure: nil, on_permanent_failure: nil, sender: nil)
6
14
  raise NoMethodError, "undefined method `#{method}' for #{object.inspect}" unless object.respond_to?(method, true)
7
15
 
@@ -11,13 +19,8 @@ module Delayed
11
19
  self.method = method.to_sym
12
20
  self.fail_cb = on_failure
13
21
  self.permanent_fail_cb = on_permanent_failure
14
- self.sender = sender
15
- begin
16
- YAML.load(YAML.dump(sender))
17
- rescue
18
- # if for some reason you can't dump the sender, just drop it
19
- self.sender = nil
20
- end
22
+ self.sender_is_object = sender.equal?(object)
23
+ self.sender_is_class = sender.is_a?(object.class)
21
24
  end
22
25
 
23
26
  def display_name
@@ -32,14 +35,15 @@ module Delayed
32
35
  def perform
33
36
  kwargs = self.kwargs || {}
34
37
 
35
- sender_is_object = sender == object
36
- sender_is_class = sender.is_a?(object.class)
38
+ # back-compat for jobs queued before we assigned these in initialize
39
+ self.sender_is_object = sender.equal?(object) if sender_is_object.nil?
40
+ self.sender_is_class = sender.is_a?(object.class) if sender_is_class.nil?
37
41
 
38
- if sender.nil? || sender_is_object || (sender_is_class && object.protected_methods.include?(method))
42
+ if sender_is_object || (sender_is_class && object.protected_methods.include?(method))
39
43
  if kwargs.empty?
40
- object.send(method, *args)
44
+ object.__send__(method, *args)
41
45
  else
42
- object.send(method, *args, **kwargs)
46
+ object.__send__(method, *args, **kwargs)
43
47
  end
44
48
  elsif kwargs.empty?
45
49
  object.public_send(method, *args)
@@ -59,9 +63,9 @@ module Delayed
59
63
  def deep_de_ar_ize(arg)
60
64
  case arg
61
65
  when Hash
62
- "{#{arg.map { |k, v| "#{deep_de_ar_ize(k)} => #{deep_de_ar_ize(v)}" }.join(', ')}}"
66
+ "{#{arg.map { |k, v| "#{deep_de_ar_ize(k)} => #{deep_de_ar_ize(v)}" }.join(", ")}}"
63
67
  when Array
64
- "[#{arg.map { |a| deep_de_ar_ize(a) }.join(', ')}]"
68
+ "[#{arg.map { |a| deep_de_ar_ize(a) }.join(", ")}]"
65
69
  when ActiveRecord::Base
66
70
  "#{arg.class}.find(#{arg.id})"
67
71
  else
@@ -73,7 +77,7 @@ module Delayed
73
77
  obj_name = object.is_a?(ActiveRecord::Base) ? "#{object.class}.find(#{object.id}).#{method}" : display_name
74
78
  kgs = kwargs || {}
75
79
  kwargs_str = kgs.map { |(k, v)| ", #{k}: #{deep_de_ar_ize(v)}" }.join
76
- "#{obj_name}(#{args.map { |a| deep_de_ar_ize(a) }.join(', ')}#{kwargs_str})"
80
+ "#{obj_name}(#{args.map { |a| deep_de_ar_ize(a) }.join(", ")}#{kwargs_str})"
77
81
  end
78
82
  end
79
83
  end
@@ -83,7 +83,7 @@ module Delayed
83
83
  def tag
84
84
  "periodic: #{@name}"
85
85
  end
86
- alias display_name tag
86
+ alias_method :display_name, :tag
87
87
 
88
88
  def self.now
89
89
  Time.zone.now
@@ -26,6 +26,7 @@ module Delayed
26
26
  :sleep_delay,
27
27
  :sleep_delay_stagger,
28
28
  :slow_exit_timeout,
29
+ :stranded_run_at_grace_period,
29
30
  :worker_health_check_type,
30
31
  :worker_health_check_config,
31
32
  :worker_procname_prefix
@@ -132,6 +133,7 @@ module Delayed
132
133
  self.fetch_batch_size = 5
133
134
  self.select_random_from_batch = false
134
135
  self.silence_periodic_log = false
136
+ self.stranded_run_at_grace_period = 10
135
137
 
136
138
  self.num_strands = ->(_strand_name) {}
137
139
  self.default_job_options = -> { {} }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- VERSION = "3.1.7"
4
+ VERSION = "3.1.9"
5
5
  end
@@ -163,7 +163,7 @@ module Delayed
163
163
  forced_latency: forced_latency
164
164
  )
165
165
  logger.debug(
166
- "Fetched and locked #{response.values.flatten.size} new jobs for workers (#{response.keys.join(', ')})."
166
+ "Fetched and locked #{response.values.flatten.size} new jobs for workers (#{response.keys.join(", ")})."
167
167
  )
168
168
  response.each do |(worker_name, locked_jobs)|
169
169
  if worker_name == prefetch_owner
@@ -267,7 +267,7 @@ module Delayed
267
267
  end
268
268
 
269
269
  def prefetch_owner
270
- "prefetch:#{Socket.gethostname rescue 'X'}"
270
+ "prefetch:#{Socket.gethostname rescue "X"}"
271
271
  end
272
272
 
273
273
  def parent_exited?
@@ -9,9 +9,9 @@ module Delayed
9
9
  ALIVE_CHECK_LINUX = '[ -d "/proc/$WORKER_PID" ]'
10
10
  ALIVE_CHECK_MAC = "ps -p $WORKER_PID > /dev/null"
11
11
  ALIVE_CHECK = RUBY_PLATFORM.include?("darwin") ? ALIVE_CHECK_MAC : ALIVE_CHECK_LINUX
12
- SCRIPT_TEMPLATE = <<-BASH
13
- WORKER_PID="%<pid>d" # an example, filled from ruby when the check is created
14
- ORIGINAL_MTIME="%<mtime>s" # an example, filled from ruby when the check is created
12
+ SCRIPT_TEMPLATE = <<~SH
13
+ WORKER_PID="%{pid}" # an example, filled from ruby when the check is created
14
+ ORIGINAL_MTIME="%{mtime}" # an example, filled from ruby when the check is created
15
15
 
16
16
  if #{ALIVE_CHECK}; then
17
17
  CURRENT_MTIME=$(#{STAT})
@@ -26,7 +26,7 @@ module Delayed
26
26
  else
27
27
  exit 255 # The process is no more, trigger a "critical" state.
28
28
  fi
29
- BASH
29
+ SH
30
30
 
31
31
  def self.mtime(pid)
32
32
  if RUBY_PLATFORM.include?("darwin")
@@ -77,7 +77,7 @@ module Delayed
77
77
  end
78
78
 
79
79
  def name
80
- @name ||= "#{Socket.gethostname rescue 'X'}:#{id}"
80
+ @name ||= "#{Socket.gethostname rescue "X"}:#{id}"
81
81
  end
82
82
 
83
83
  def process_name=(new_name)
@@ -100,7 +100,7 @@ module Delayed
100
100
  def start
101
101
  logger.info "Starting worker"
102
102
  self.process_name =
103
- "start:#{Settings.worker_procname_prefix}#{@queue_name}:#{min_priority || 0}:#{max_priority || 'max'}"
103
+ "start:#{Settings.worker_procname_prefix}#{@queue_name}:#{min_priority || 0}:#{max_priority || "max"}"
104
104
  @self_pipe = IO.pipe
105
105
  work_queue.init
106
106
 
@@ -170,7 +170,7 @@ module Delayed
170
170
 
171
171
  self.class.lifecycle.run_callbacks(:loop, self) do
172
172
  self.process_name =
173
- "pop:#{Settings.worker_procname_prefix}#{@queue_name}:#{min_priority || 0}:#{max_priority || 'max'}"
173
+ "pop:#{Settings.worker_procname_prefix}#{@queue_name}:#{min_priority || 0}:#{max_priority || "max"}"
174
174
  job = self.class.lifecycle.run_callbacks(:pop, self) do
175
175
  work_queue.get_and_lock_next_available(name, config)
176
176
  end
@@ -196,7 +196,7 @@ module Delayed
196
196
  end
197
197
  else
198
198
  self.process_name =
199
- "wait:#{Settings.worker_procname_prefix}#{@queue_name}:#{min_priority || 0}:#{max_priority || 'max'}"
199
+ "wait:#{Settings.worker_procname_prefix}#{@queue_name}:#{min_priority || 0}:#{max_priority || "max"}"
200
200
  sleep(Settings.sleep_delay + (rand * Settings.sleep_delay_stagger)) unless exit?
201
201
  end
202
202
  end
@@ -220,7 +220,7 @@ module Delayed
220
220
  end
221
221
  job.destroy
222
222
  end
223
- logger.info("Completed #{log_job(job, :short)} #{format('%.0fms', (runtime * 1000))}")
223
+ logger.info("Completed #{log_job(job, :short)} #{format("%.0fms", (runtime * 1000))}")
224
224
  end
225
225
  rescue ::Delayed::RetriableError => e
226
226
  can_retry = job.attempts + 1 < job.inferred_max_attempts
@@ -279,7 +279,7 @@ module Delayed
279
279
  previous_tmpdir = ENV.fetch("TMPDIR", nil)
280
280
 
281
281
  self.class.running_job(job) do
282
- dir = Dir.mktmpdir("job-#{job.id}-#{name.gsub(/[^\w.]/, '.')}-")
282
+ dir = Dir.mktmpdir("job-#{job.id}-#{name.gsub(/[^\w.]/, ".")}-")
283
283
  begin
284
284
  ENV["TMPDIR"] = dir
285
285
  yield
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: 3.1.7
4
+ version: 3.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2023-01-13 00:00:00.000000000 Z
13
+ date: 2023-05-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -285,33 +285,19 @@ dependencies:
285
285
  - !ruby/object:Gem::Version
286
286
  version: '3.10'
287
287
  - !ruby/object:Gem::Dependency
288
- name: rubocop
288
+ name: rubocop-inst
289
289
  requirement: !ruby/object:Gem::Requirement
290
290
  requirements:
291
291
  - - "~>"
292
292
  - !ruby/object:Gem::Version
293
- version: '1.19'
293
+ version: '1'
294
294
  type: :development
295
295
  prerelease: false
296
296
  version_requirements: !ruby/object:Gem::Requirement
297
297
  requirements:
298
298
  - - "~>"
299
299
  - !ruby/object:Gem::Version
300
- version: '1.19'
301
- - !ruby/object:Gem::Dependency
302
- name: rubocop-performance
303
- requirement: !ruby/object:Gem::Requirement
304
- requirements:
305
- - - "~>"
306
- - !ruby/object:Gem::Version
307
- version: 1.12.0
308
- type: :development
309
- prerelease: false
310
- version_requirements: !ruby/object:Gem::Requirement
311
- requirements:
312
- - - "~>"
313
- - !ruby/object:Gem::Version
314
- version: 1.12.0
300
+ version: '1'
315
301
  - !ruby/object:Gem::Dependency
316
302
  name: rubocop-rails
317
303
  requirement: !ruby/object:Gem::Requirement