inst-jobs 2.0.0 → 3.0.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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/db/migrate/20101216224513_create_delayed_jobs.rb +9 -7
  3. data/db/migrate/20110531144916_cleanup_delayed_jobs_indexes.rb +8 -13
  4. data/db/migrate/20110610213249_optimize_delayed_jobs.rb +8 -8
  5. data/db/migrate/20110831210257_add_delayed_jobs_next_in_strand.rb +25 -25
  6. data/db/migrate/20120510004759_delayed_jobs_delete_trigger_lock_for_update.rb +4 -8
  7. data/db/migrate/20120531150712_drop_psql_jobs_pop_fn.rb +1 -3
  8. data/db/migrate/20120607164022_delayed_jobs_use_advisory_locks.rb +11 -15
  9. data/db/migrate/20120607181141_index_jobs_on_locked_by.rb +1 -1
  10. data/db/migrate/20120608191051_add_jobs_run_at_index.rb +2 -2
  11. data/db/migrate/20120927184213_change_delayed_jobs_handler_to_text.rb +1 -1
  12. data/db/migrate/20140505215510_copy_failed_jobs_original_id.rb +2 -3
  13. data/db/migrate/20150807133223_add_max_concurrent_to_jobs.rb +9 -13
  14. data/db/migrate/20151210162949_improve_max_concurrent.rb +4 -8
  15. data/db/migrate/20161206323555_add_back_default_string_limits_jobs.rb +3 -2
  16. data/db/migrate/20181217155351_speed_up_max_concurrent_triggers.rb +13 -17
  17. data/db/migrate/20200330230722_add_id_to_get_delayed_jobs_index.rb +8 -8
  18. data/db/migrate/20200824222232_speed_up_max_concurrent_delete_trigger.rb +72 -77
  19. data/db/migrate/20200825011002_add_strand_order_override.rb +93 -97
  20. data/db/migrate/20210809145804_add_n_strand_index.rb +12 -0
  21. data/db/migrate/20210812210128_add_singleton_column.rb +200 -0
  22. data/db/migrate/20210917232626_add_delete_conflicting_singletons_before_unlock_trigger.rb +27 -0
  23. data/db/migrate/20210928174754_fix_singleton_condition_in_before_insert.rb +56 -0
  24. data/db/migrate/20210929204903_update_conflicting_singleton_function_to_use_index.rb +27 -0
  25. data/exe/inst_jobs +3 -2
  26. data/lib/delayed/backend/active_record.rb +211 -168
  27. data/lib/delayed/backend/base.rb +110 -72
  28. data/lib/delayed/batch.rb +11 -9
  29. data/lib/delayed/cli.rb +98 -84
  30. data/lib/delayed/core_ext/kernel.rb +4 -2
  31. data/lib/delayed/daemon.rb +70 -74
  32. data/lib/delayed/job_tracking.rb +26 -25
  33. data/lib/delayed/lifecycle.rb +27 -23
  34. data/lib/delayed/log_tailer.rb +17 -17
  35. data/lib/delayed/logging.rb +13 -16
  36. data/lib/delayed/message_sending.rb +43 -52
  37. data/lib/delayed/performable_method.rb +6 -8
  38. data/lib/delayed/periodic.rb +72 -68
  39. data/lib/delayed/plugin.rb +2 -4
  40. data/lib/delayed/pool.rb +205 -168
  41. data/lib/delayed/server/helpers.rb +6 -6
  42. data/lib/delayed/server.rb +51 -54
  43. data/lib/delayed/settings.rb +94 -81
  44. data/lib/delayed/testing.rb +21 -22
  45. data/lib/delayed/version.rb +1 -1
  46. data/lib/delayed/work_queue/in_process.rb +21 -17
  47. data/lib/delayed/work_queue/parent_process/client.rb +55 -53
  48. data/lib/delayed/work_queue/parent_process/server.rb +245 -207
  49. data/lib/delayed/work_queue/parent_process.rb +52 -53
  50. data/lib/delayed/worker/consul_health_check.rb +32 -33
  51. data/lib/delayed/worker/health_check.rb +34 -26
  52. data/lib/delayed/worker/null_health_check.rb +3 -1
  53. data/lib/delayed/worker/process_helper.rb +8 -9
  54. data/lib/delayed/worker.rb +272 -241
  55. data/lib/delayed/yaml_extensions.rb +12 -10
  56. data/lib/delayed_job.rb +37 -37
  57. data/lib/inst-jobs.rb +1 -1
  58. data/spec/active_record_job_spec.rb +143 -139
  59. data/spec/delayed/cli_spec.rb +7 -7
  60. data/spec/delayed/daemon_spec.rb +10 -9
  61. data/spec/delayed/message_sending_spec.rb +16 -9
  62. data/spec/delayed/periodic_spec.rb +14 -21
  63. data/spec/delayed/server_spec.rb +38 -38
  64. data/spec/delayed/settings_spec.rb +26 -25
  65. data/spec/delayed/work_queue/in_process_spec.rb +7 -8
  66. data/spec/delayed/work_queue/parent_process/client_spec.rb +17 -12
  67. data/spec/delayed/work_queue/parent_process/server_spec.rb +117 -41
  68. data/spec/delayed/work_queue/parent_process_spec.rb +21 -23
  69. data/spec/delayed/worker/consul_health_check_spec.rb +37 -50
  70. data/spec/delayed/worker/health_check_spec.rb +60 -52
  71. data/spec/delayed/worker_spec.rb +44 -21
  72. data/spec/sample_jobs.rb +45 -15
  73. data/spec/shared/delayed_batch.rb +74 -67
  74. data/spec/shared/delayed_method.rb +143 -102
  75. data/spec/shared/performable_method.rb +39 -38
  76. data/spec/shared/shared_backend.rb +550 -437
  77. data/spec/shared/testing.rb +14 -14
  78. data/spec/shared/worker.rb +156 -148
  79. data/spec/shared_jobs_specs.rb +13 -13
  80. data/spec/spec_helper.rb +53 -55
  81. metadata +148 -82
  82. data/lib/delayed/backend/redis/bulk_update.lua +0 -50
  83. data/lib/delayed/backend/redis/destroy_job.lua +0 -2
  84. data/lib/delayed/backend/redis/enqueue.lua +0 -29
  85. data/lib/delayed/backend/redis/fail_job.lua +0 -5
  86. data/lib/delayed/backend/redis/find_available.lua +0 -3
  87. data/lib/delayed/backend/redis/functions.rb +0 -59
  88. data/lib/delayed/backend/redis/get_and_lock_next_available.lua +0 -17
  89. data/lib/delayed/backend/redis/includes/jobs_common.lua +0 -203
  90. data/lib/delayed/backend/redis/job.rb +0 -535
  91. data/lib/delayed/backend/redis/set_running.lua +0 -5
  92. data/lib/delayed/backend/redis/tickle_strand.lua +0 -2
  93. data/spec/gemfiles/42.gemfile +0 -7
  94. data/spec/gemfiles/50.gemfile +0 -7
  95. data/spec/gemfiles/51.gemfile +0 -7
  96. data/spec/gemfiles/52.gemfile +0 -7
  97. data/spec/gemfiles/60.gemfile +0 -7
  98. data/spec/redis_job_spec.rb +0 -148
@@ -1,97 +1,93 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fileutils'
3
+ require "fileutils"
4
4
 
5
5
  module Delayed
6
- # Daemon controls the parent proces that runs the Pool and monitors the Worker processes.
7
- class Daemon
8
- attr_reader :pid_folder
6
+ # Daemon controls the parent proces that runs the Pool and monitors the Worker processes.
7
+ class Daemon
8
+ attr_reader :pid_folder
9
9
 
10
- def initialize(pid_folder)
11
- @pid_folder = pid_folder
12
- end
10
+ def initialize(pid_folder)
11
+ @pid_folder = pid_folder
12
+ end
13
13
 
14
- def status(print: true, pid: self.pid)
15
- alive = pid && (Process.kill(0, pid) rescue false) && :running
16
- alive ||= :draining if pid && Process.kill(0, -pid) rescue false
17
- if alive
18
- puts "Delayed jobs #{alive}, pool PID: #{pid}" if print
19
- else
20
- puts "No delayed jobs pool running" if print && print != :alive
14
+ def status(print: true, pid: self.pid)
15
+ alive = pid && (Process.kill(0, pid) rescue false) && :running
16
+ alive ||= :draining if pid && Process.kill(0, -pid) rescue false
17
+ if alive
18
+ puts "Delayed jobs #{alive}, pool PID: #{pid}" if print
19
+ elsif print && print != :alive
20
+ puts "No delayed jobs pool running"
21
+ end
22
+ alive
21
23
  end
22
- alive
23
- end
24
24
 
25
- def daemonize!
26
- FileUtils.mkdir_p(pid_folder)
27
- puts "Daemonizing..."
25
+ def daemonize!
26
+ FileUtils.mkdir_p(pid_folder)
27
+ puts "Daemonizing..."
28
28
 
29
- exit if fork
30
- Process.setsid
31
- exit if fork
32
- Process.setpgrp
29
+ exit if fork
30
+ Process.setsid
31
+ exit if fork
32
+ Process.setpgrp
33
33
 
34
- @daemon = true
35
- lock_file = File.open(pid_file, 'wb')
36
- # someone else is already running; just exit
37
- unless lock_file.flock(File::LOCK_EX | File::LOCK_NB)
38
- exit
39
- end
40
- at_exit { lock_file.flock(File::LOCK_UN) }
41
- lock_file.puts(Process.pid.to_s)
42
- lock_file.flush
34
+ @daemon = true
35
+ lock_file = File.open(pid_file, "wb")
36
+ # someone else is already running; just exit
37
+ exit unless lock_file.flock(File::LOCK_EX | File::LOCK_NB)
38
+ at_exit { lock_file.flock(File::LOCK_UN) }
39
+ lock_file.puts(Process.pid.to_s)
40
+ lock_file.flush
43
41
 
44
- # if we blow up so badly that we can't syslog the error, try to send
45
- # it somewhere useful
46
- last_ditch_logfile = Settings.last_ditch_logfile || "log/delayed_job.log"
47
- if last_ditch_logfile[0] != '|'
48
- last_ditch_logfile = Settings.expand_rails_path(last_ditch_logfile)
42
+ # if we blow up so badly that we can't syslog the error, try to send
43
+ # it somewhere useful
44
+ last_ditch_logfile = Settings.last_ditch_logfile || "log/delayed_job.log"
45
+ last_ditch_logfile = Settings.expand_rails_path(last_ditch_logfile) if last_ditch_logfile[0] != "|"
46
+ $stdin.reopen("/dev/null")
47
+ $stdout.reopen(open(last_ditch_logfile, "a")) # rubocop:disable Security/Open
48
+ $stderr.reopen($stdout)
49
+ $stdout.sync = $stderr.sync = true
49
50
  end
50
- STDIN.reopen("/dev/null")
51
- STDOUT.reopen(open(last_ditch_logfile, 'a'))
52
- STDERR.reopen(STDOUT)
53
- STDOUT.sync = STDERR.sync = true
54
- end
55
51
 
56
- # stop the currently running daemon (not this current process, the one in the pid_file)
57
- def stop(kill: false, pid: self.pid)
58
- alive = status(pid: pid, print: false)
59
- if alive == :running || (kill && alive == :draining)
60
- puts "Stopping pool #{pid}..."
61
- signal = kill ? 'TERM' : 'QUIT'
62
- begin
63
- Process.kill(signal, pid)
64
- rescue Errno::ESRCH
65
- # ignore if the pid no longer exists
52
+ # stop the currently running daemon (not this current process, the one in the pid_file)
53
+ def stop(kill: false, pid: self.pid)
54
+ alive = status(pid: pid, print: false)
55
+ if alive == :running || (kill && alive == :draining)
56
+ puts "Stopping pool #{pid}..."
57
+ signal = kill ? "TERM" : "QUIT"
58
+ begin
59
+ Process.kill(signal, pid)
60
+ rescue Errno::ESRCH
61
+ # ignore if the pid no longer exists
62
+ end
63
+ wait(kill)
64
+ else
65
+ status
66
66
  end
67
- wait(kill)
68
- else
69
- status
70
67
  end
71
- end
72
68
 
73
- def wait(kill)
74
- if kill
75
- sleep(0.5) while status(pid: pid, print: false)
76
- else
77
- sleep(0.5) while status(pid: pid, print: false) == :running
69
+ def wait(kill)
70
+ if kill
71
+ sleep(0.5) while status(pid: pid, print: false)
72
+ else
73
+ sleep(0.5) while status(pid: pid, print: false) == :running
74
+ end
78
75
  end
79
- end
80
76
 
81
- def pid_file
82
- File.join(pid_folder, 'delayed_jobs_pool.pid')
83
- end
77
+ def pid_file
78
+ File.join(pid_folder, "delayed_jobs_pool.pid")
79
+ end
84
80
 
85
- def pid
86
- if File.file?(pid_file)
87
- pid = File.read(pid_file).to_i
88
- pid = nil unless pid > 0
81
+ def pid
82
+ if File.file?(pid_file)
83
+ pid = File.read(pid_file).to_i
84
+ pid = nil unless pid.positive?
85
+ end
86
+ pid
89
87
  end
90
- pid
91
- end
92
88
 
93
- def daemonized?
94
- !!@daemon
89
+ def daemonized?
90
+ !!@daemon
91
+ end
95
92
  end
96
93
  end
97
- end
@@ -1,33 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- # Used when a block of code wants to track what jobs are created,
5
- # for instance in tests.
6
- # Delayed::Job.track_jobs { ...block... } returns a JobTracking object
7
- # Right now this just tracks created jobs, it could be expanded to track a
8
- # lot more about what's going on in Delayed Jobs as it's needed.
9
- class JobTracking < Struct.new(:created)
10
- def self.track
11
- @current_tracking = self.new
12
- yield
13
- tracking = @current_tracking
14
- @current_tracking = nil
15
- tracking
16
- end
4
+ # Used when a block of code wants to track what jobs are created,
5
+ # for instance in tests.
6
+ # Delayed::Job.track_jobs { ...block... } returns a JobTracking object
7
+ # Right now this just tracks created jobs, it could be expanded to track a
8
+ # lot more about what's going on in Delayed Jobs as it's needed.
9
+ JobTracking = Struct.new(:created) do
10
+ def self.track
11
+ @current_tracking = new
12
+ yield
13
+ tracking = @current_tracking
14
+ @current_tracking = nil
15
+ tracking
16
+ end
17
17
 
18
- def self.job_created(job)
19
- @current_tracking.try(:job_created, job)
20
- end
18
+ def self.job_created(job)
19
+ @current_tracking.try(:job_created, job)
20
+ end
21
21
 
22
- def job_created(job)
23
- return unless job
24
- @lock.synchronize { self.created << job }
25
- end
22
+ def job_created(job)
23
+ return unless job
26
24
 
27
- def initialize
28
- super
29
- self.created = []
30
- @lock = Mutex.new
25
+ @lock.synchronize { created << job }
26
+ end
27
+
28
+ def initialize
29
+ super
30
+ self.created = []
31
+ @lock = Mutex.new
32
+ end
31
33
  end
32
34
  end
33
- end
@@ -1,28 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- class InvalidCallback < Exception; end
4
+ class InvalidCallback < RuntimeError; end
5
5
 
6
6
  class Lifecycle
7
7
  EVENTS = {
8
- :error => [:worker, :job, :exception],
9
- :exceptional_exit => [:worker, :exception],
10
- :execute => [:worker],
11
- :invoke_job => [:job],
12
- :loop => [:worker],
13
- :perform => [:worker, :job],
14
- :pop => [:worker],
15
- :work_queue_pop => [:work_queue, :worker_config],
16
- :check_for_work => [:work_queue],
17
- }
8
+ error: %i[worker job exception],
9
+ exceptional_exit: %i[worker exception],
10
+ execute: [:worker],
11
+ invoke_job: [:job],
12
+ loop: [:worker],
13
+ perform: %i[worker job],
14
+ pop: [:worker],
15
+ retry: %i[worker job exception],
16
+ work_queue_pop: %i[work_queue worker_config],
17
+ check_for_work: [:work_queue]
18
+ }.freeze
18
19
 
19
20
  def initialize
20
21
  reset!
21
22
  end
22
23
 
23
24
  def reset!
24
- @callbacks = EVENTS.keys.inject({}) { |hash, e| hash[e] = Callback.new; hash }
25
- Delayed::Worker.plugins.each { |plugin| plugin.reset! }
25
+ @callbacks = EVENTS.keys.each_with_object({}) do |e, hash|
26
+ hash[e] = Callback.new
27
+ hash
28
+ end
29
+ Delayed::Worker.plugins.each(&:reset!)
26
30
  end
27
31
 
28
32
  def before(event, &block)
@@ -38,7 +42,7 @@ module Delayed
38
42
  end
39
43
 
40
44
  def run_callbacks(event, *args, &block)
41
- missing_callback(event) unless @callbacks.has_key?(event)
45
+ missing_callback(event) unless @callbacks.key?(event)
42
46
 
43
47
  unless EVENTS[event].size == args.size
44
48
  raise ArgumentError, "Callback #{event} expects #{EVENTS[event].size} parameter(s): #{EVENTS[event].join(', ')}"
@@ -49,15 +53,15 @@ module Delayed
49
53
 
50
54
  private
51
55
 
52
- def add(type, event, &block)
53
- missing_callback(event) unless @callbacks.has_key?(event)
56
+ def add(type, event, &block)
57
+ missing_callback(event) unless @callbacks.key?(event)
54
58
 
55
- @callbacks[event].add(type, &block)
56
- end
59
+ @callbacks[event].add(type, &block)
60
+ end
57
61
 
58
- def missing_callback(event)
59
- raise InvalidCallback, "Unknown callback event: #{event}"
60
- end
62
+ def missing_callback(event)
63
+ raise InvalidCallback, "Unknown callback event: #{event}"
64
+ end
61
65
  end
62
66
 
63
67
  class Callback
@@ -66,7 +70,7 @@ module Delayed
66
70
  @after = []
67
71
 
68
72
  # Identity proc. Avoids special cases when there is no existing around chain.
69
- @around = lambda { |*args, &block| block.call(*args) }
73
+ @around = ->(*args, &block) { block.call(*args) }
70
74
  end
71
75
 
72
76
  def execute(*args, &block)
@@ -84,7 +88,7 @@ module Delayed
84
88
  @after << callback
85
89
  when :around
86
90
  chain = @around # use a local variable so that the current chain is closed over in the following lambda
87
- @around = lambda { |*a, &block| chain.call(*a) { |*b| callback.call(*b, &block) } }
91
+ @around = ->(*a, &block) { chain.call(*a) { |*b| callback.call(*b, &block) } }
88
92
  else
89
93
  raise InvalidCallback, "Invalid callback type: #{type}"
90
94
  end
@@ -1,24 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- class LogTailer
5
- def run
6
- if Rails.logger.respond_to?(:log_path)
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
10
- else
11
- return
12
- end
13
- Rails.logger.auto_flushing = true if Rails.logger.respond_to?(:auto_flushing=)
14
- Thread.new do
15
- f = File.open(log_path, 'r')
16
- f.seek(0, IO::SEEK_END)
17
- loop do
18
- content = f.read
19
- content.present? ? STDOUT.print(content) : sleep(0.5)
4
+ class LogTailer
5
+ def run
6
+ if Rails.logger.respond_to?(:log_path)
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
10
+ else
11
+ return
12
+ end
13
+ Rails.logger.auto_flushing = true if Rails.logger.respond_to?(:auto_flushing=)
14
+ Thread.new do
15
+ f = File.open(log_path, "r")
16
+ f.seek(0, IO::SEEK_END)
17
+ loop do
18
+ content = f.read
19
+ content.present? ? $stdout.print(content) : sleep(0.5)
20
+ end
20
21
  end
21
22
  end
22
23
  end
23
24
  end
24
- end
@@ -1,30 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
3
+ require "date"
4
4
 
5
5
  module Delayed
6
6
  module Logging
7
- TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.%6N'.freeze
7
+ TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S.%6N"
8
8
  private_constant :TIMESTAMP_FORMAT
9
9
 
10
- FORMAT = '%s - %s'
10
+ FORMAT = "%s - %s"
11
11
  private_constant :FORMAT
12
12
 
13
-
14
13
  def self.logger
15
14
  return @logger if @logger
16
- if defined?(Rails.logger) && Rails.logger
17
- @logger = Rails.logger
18
- else
19
- @logger = ::Logger.new(STDOUT).tap do |logger|
20
- logger.formatter = ->(_, time, _, msg) {
21
- FORMAT % [
22
- time.strftime(TIMESTAMP_FORMAT),
23
- msg
24
- ]
25
- }
26
- end
27
- end
15
+
16
+ @logger = if defined?(Rails.logger) && Rails.logger
17
+ Rails.logger
18
+ else
19
+ ::Logger.new($stdout).tap do |logger|
20
+ logger.formatter = lambda { |_, time, _, msg|
21
+ format(FORMAT, time.strftime(TIMESTAMP_FORMAT), msg)
22
+ }
23
+ end
24
+ end
28
25
  end
29
26
 
30
27
  def logger
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if ::Rails.env.test? || ::Rails.env.development?
4
- require 'debug_inspector'
5
- end
3
+ require "debug_inspector" if ::Rails.env.test? || ::Rails.env.development?
6
4
 
7
5
  module Delayed
8
6
  module MessageSending
@@ -14,12 +12,12 @@ module Delayed
14
12
  @sender = sender
15
13
  end
16
14
 
17
- def method_missing(method, *args, **kwargs)
15
+ def method_missing(method, *args, **kwargs) # rubocop:disable Style/MissingRespondToMissing
18
16
  # method doesn't exist? must be method_missing; assume private access
19
17
  @sender = nil if !@sender.nil? &&
20
- !@object.methods.include?(method) &&
21
- !@object.protected_methods.include?(method) &&
22
- !@object.private_methods.include?(method)
18
+ @object.methods.exclude?(method) &&
19
+ @object.protected_methods.exclude?(method) &&
20
+ @object.private_methods.exclude?(method)
23
21
 
24
22
  sender_is_object = @sender == @object
25
23
  sender_is_class = @sender.is_a?(@object.class)
@@ -33,51 +31,47 @@ module Delayed
33
31
  end
34
32
 
35
33
  if @synchronous
36
- if @sender.nil? || sender_is_object || sender_is_class && @object.protected_methods.include?(method)
37
- if kwargs.empty?
38
- return @object.send(method, *args)
39
- else
40
- return @object.send(method, *args, **kwargs)
41
- end
42
- end
43
-
44
- if kwargs.empty?
45
- return @object.public_send(method, *args)
46
- else
47
- return @object.public_send(method, *args, **kwargs)
34
+ if @sender.nil? || sender_is_object || (sender_is_class && @object.protected_methods.include?(method))
35
+ return @object.send(method, *args) if kwargs.empty?
36
+
37
+ return @object.send(method, *args, **kwargs)
48
38
  end
39
+
40
+ return @object.public_send(method, *args) if kwargs.empty?
41
+
42
+ return @object.public_send(method, *args, **kwargs)
49
43
  end
50
44
 
51
45
  ignore_transaction = @enqueue_args.delete(:ignore_transaction)
52
46
  on_failure = @enqueue_args.delete(:on_failure)
53
47
  on_permanent_failure = @enqueue_args.delete(:on_permanent_failure)
54
- if !ignore_transaction
48
+ unless ignore_transaction
55
49
  # delay queuing up the job in another database until the results of the current
56
50
  # transaction are visible
57
51
  connection = @object.class.connection if @object.class.respond_to?(:connection)
58
52
  connection ||= @object.connection if @object.respond_to?(:connection)
59
53
  connection ||= ::ActiveRecord::Base.connection
60
54
 
61
- if (::Delayed::Job != ::Delayed::Backend::ActiveRecord::Job || connection != ::Delayed::Job.connection)
55
+ if ::Delayed::Job != ::Delayed::Backend::ActiveRecord::Job || connection != ::Delayed::Job.connection
62
56
  connection.after_transaction_commit do
63
57
  ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object, method,
64
- args: args, kwargs: kwargs,
65
- on_failure: on_failure,
66
- on_permanent_failure: on_permanent_failure,
67
- sender: @sender),
68
- **@enqueue_args)
58
+ args: args, kwargs: kwargs,
59
+ on_failure: on_failure,
60
+ on_permanent_failure: on_permanent_failure,
61
+ sender: @sender),
62
+ **@enqueue_args)
69
63
  end
70
64
  return nil
71
65
  end
72
66
  end
73
67
 
74
68
  result = ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object, method,
75
- args: args,
76
- kwargs: kwargs,
77
- on_failure: on_failure,
78
- on_permanent_failure: on_permanent_failure,
79
- sender: @sender),
80
- **@enqueue_args)
69
+ args: args,
70
+ kwargs: kwargs,
71
+ on_failure: on_failure,
72
+ on_permanent_failure: on_permanent_failure,
73
+ sender: @sender),
74
+ **@enqueue_args)
81
75
  result = nil unless ignore_transaction
82
76
  result
83
77
  end
@@ -85,10 +79,8 @@ module Delayed
85
79
 
86
80
  def delay(sender: nil, **enqueue_args)
87
81
  # support procs/methods as enqueue arguments
88
- enqueue_args.each do |k,v|
89
- if v.respond_to?(:call)
90
- enqueue_args[k] = v.call(self)
91
- end
82
+ enqueue_args.each do |k, v|
83
+ enqueue_args[k] = v.call(self) if v.respond_to?(:call)
92
84
  end
93
85
 
94
86
  sender ||= __calculate_sender_for_delay
@@ -103,33 +95,32 @@ module Delayed
103
95
  end
104
96
 
105
97
  module ClassMethods
106
- KWARG_ARG_TYPES = %i{key keyreq keyrest}.freeze
98
+ KWARG_ARG_TYPES = %i[key keyreq keyrest].freeze
107
99
  private_constant :KWARG_ARG_TYPES
108
100
 
109
101
  def handle_asynchronously(method_name, **enqueue_args)
110
- aliased_method, punctuation = method_name.to_s.sub(/([?!=])$/, ''), $1
111
-
112
- if public_method_defined?(method_name)
113
- visibility = :public
114
- elsif private_method_defined?(method_name)
115
- visibility = :private
116
- else
117
- visibility = :protected
118
- end
119
-
120
- if has_kwargs? method_name
102
+ visibility = if public_method_defined?(method_name)
103
+ :public
104
+ elsif private_method_defined?(method_name)
105
+ :private
106
+ else
107
+ :protected
108
+ end
109
+
110
+ if kwargs? method_name
121
111
  generated_delayed_methods.class_eval do
122
- define_method(method_name, -> (*args, synchronous: false, **kwargs) do
112
+ define_method(method_name, lambda do |*args, synchronous: false, **kwargs|
123
113
  if synchronous
124
114
  super(*args, **kwargs)
125
115
  else
126
- delay(sender: __calculate_sender_for_delay, **enqueue_args).method_missing(method_name, *args, synchronous: true, **kwargs)
116
+ delay(sender: __calculate_sender_for_delay, **enqueue_args)
117
+ .method_missing(method_name, *args, synchronous: true, **kwargs)
127
118
  end
128
119
  end)
129
120
  end
130
121
  else
131
122
  generated_delayed_methods.class_eval do
132
- define_method(method_name, -> (*args, synchronous: false) do
123
+ define_method(method_name, lambda do |*args, synchronous: false|
133
124
  if synchronous
134
125
  super(*args)
135
126
  else
@@ -150,7 +141,7 @@ module Delayed
150
141
  end
151
142
  end
152
143
 
153
- def has_kwargs?(method_name)
144
+ def kwargs?(method_name)
154
145
  original_arg_types = instance_method(method_name).parameters.map(&:first)
155
146
  original_arg_types.any? { |arg_type| KWARG_ARG_TYPES.include?(arg_type) }
156
147
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- class PerformableMethod < Struct.new(:object, :method, :args, :kwargs, :fail_cb, :permanent_fail_cb, :sender)
4
+ PerformableMethod = Struct.new(:object, :method, :args, :kwargs, :fail_cb, :permanent_fail_cb, :sender) do # rubocop:disable Lint/StructNewOverride
5
5
  def initialize(object, method, args: [], kwargs: {}, on_failure: nil, on_permanent_failure: nil, sender: nil)
6
6
  raise NoMethodError, "undefined method `#{method}' for #{object.inspect}" unless object.respond_to?(method, true)
7
7
 
@@ -35,18 +35,16 @@ module Delayed
35
35
  sender_is_object = sender == object
36
36
  sender_is_class = sender.is_a?(object.class)
37
37
 
38
- if sender.nil? || sender_is_object || sender_is_class && object.protected_methods.include?(method)
38
+ if sender.nil? || sender_is_object || (sender_is_class && object.protected_methods.include?(method))
39
39
  if kwargs.empty?
40
40
  object.send(method, *args)
41
41
  else
42
42
  object.send(method, *args, **kwargs)
43
43
  end
44
+ elsif kwargs.empty?
45
+ object.public_send(method, *args)
44
46
  else
45
- if kwargs.empty?
46
- object.public_send(method, *args)
47
- else
48
- object.public_send(method, *args, **kwargs)
49
- end
47
+ object.public_send(method, *args, **kwargs)
50
48
  end
51
49
  end
52
50
 
@@ -74,7 +72,7 @@ module Delayed
74
72
  def full_name
75
73
  obj_name = object.is_a?(ActiveRecord::Base) ? "#{object.class}.find(#{object.id}).#{method}" : display_name
76
74
  kgs = kwargs || {}
77
- kwargs_str = kgs.map { |(k, v)| ", #{k}: #{deep_de_ar_ize(v)}"}.join("")
75
+ kwargs_str = kgs.map { |(k, v)| ", #{k}: #{deep_de_ar_ize(v)}" }.join
78
76
  "#{obj_name}(#{args.map { |a| deep_de_ar_ize(a) }.join(', ')}#{kwargs_str})"
79
77
  end
80
78
  end