inst-jobs 0.16.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/db/migrate/20101216224513_create_delayed_jobs.rb +2 -0
  3. data/db/migrate/20110208031356_add_delayed_jobs_tag.rb +2 -0
  4. data/db/migrate/20110426161613_add_delayed_jobs_max_attempts.rb +2 -0
  5. data/db/migrate/20110516225834_add_delayed_jobs_strand.rb +2 -0
  6. data/db/migrate/20110531144916_cleanup_delayed_jobs_indexes.rb +2 -0
  7. data/db/migrate/20110610213249_optimize_delayed_jobs.rb +2 -0
  8. data/db/migrate/20110831210257_add_delayed_jobs_next_in_strand.rb +2 -0
  9. data/db/migrate/20120510004759_delayed_jobs_delete_trigger_lock_for_update.rb +2 -0
  10. data/db/migrate/20120531150712_drop_psql_jobs_pop_fn.rb +2 -0
  11. data/db/migrate/20120607164022_delayed_jobs_use_advisory_locks.rb +2 -0
  12. data/db/migrate/20120607181141_index_jobs_on_locked_by.rb +2 -0
  13. data/db/migrate/20120608191051_add_jobs_run_at_index.rb +2 -0
  14. data/db/migrate/20120927184213_change_delayed_jobs_handler_to_text.rb +2 -0
  15. data/db/migrate/20140505215131_add_failed_jobs_original_job_id.rb +2 -0
  16. data/db/migrate/20140505215510_copy_failed_jobs_original_id.rb +2 -0
  17. data/db/migrate/20140505223637_drop_failed_jobs_original_id.rb +2 -0
  18. data/db/migrate/20140512213941_add_source_to_jobs.rb +2 -0
  19. data/db/migrate/20150807133223_add_max_concurrent_to_jobs.rb +2 -0
  20. data/db/migrate/20151123210429_add_expires_at_to_jobs.rb +2 -0
  21. data/db/migrate/20151210162949_improve_max_concurrent.rb +2 -0
  22. data/db/migrate/20161206323555_add_back_default_string_limits_jobs.rb +2 -0
  23. data/db/migrate/20181217155351_speed_up_max_concurrent_triggers.rb +2 -0
  24. data/db/migrate/20190726154743_make_critical_columns_not_null.rb +2 -0
  25. data/db/migrate/20200330230722_add_id_to_get_delayed_jobs_index.rb +2 -0
  26. data/db/migrate/20200824222232_speed_up_max_concurrent_delete_trigger.rb +2 -0
  27. data/db/migrate/20200825011002_add_strand_order_override.rb +2 -0
  28. data/lib/delayed/backend/active_record.rb +6 -4
  29. data/lib/delayed/backend/base.rb +34 -20
  30. data/lib/delayed/backend/redis/functions.rb +2 -0
  31. data/lib/delayed/backend/redis/job.rb +2 -0
  32. data/lib/delayed/batch.rb +5 -3
  33. data/lib/delayed/cli.rb +2 -0
  34. data/lib/delayed/daemon.rb +2 -0
  35. data/lib/delayed/engine.rb +2 -0
  36. data/lib/delayed/job_tracking.rb +2 -0
  37. data/lib/delayed/lifecycle.rb +2 -0
  38. data/lib/delayed/log_tailer.rb +2 -0
  39. data/lib/delayed/logging.rb +2 -0
  40. data/lib/delayed/message_sending.rb +48 -111
  41. data/lib/delayed/performable_method.rb +15 -6
  42. data/lib/delayed/periodic.rb +6 -4
  43. data/lib/delayed/plugin.rb +2 -0
  44. data/lib/delayed/pool.rb +2 -0
  45. data/lib/delayed/server.rb +2 -0
  46. data/lib/delayed/server/helpers.rb +2 -0
  47. data/lib/delayed/settings.rb +2 -0
  48. data/lib/delayed/testing.rb +2 -0
  49. data/lib/delayed/version.rb +3 -1
  50. data/lib/delayed/work_queue/in_process.rb +2 -0
  51. data/lib/delayed/work_queue/parent_process.rb +2 -0
  52. data/lib/delayed/work_queue/parent_process/client.rb +2 -0
  53. data/lib/delayed/work_queue/parent_process/server.rb +2 -0
  54. data/lib/delayed/worker.rb +2 -0
  55. data/lib/delayed/worker/consul_health_check.rb +2 -0
  56. data/lib/delayed/worker/health_check.rb +2 -0
  57. data/lib/delayed/worker/null_health_check.rb +2 -0
  58. data/lib/delayed/worker/process_helper.rb +2 -0
  59. data/lib/delayed/yaml_extensions.rb +2 -0
  60. data/lib/delayed_job.rb +2 -0
  61. data/lib/inst-jobs.rb +2 -0
  62. data/spec/active_record_job_spec.rb +4 -2
  63. data/spec/delayed/cli_spec.rb +2 -0
  64. data/spec/delayed/daemon_spec.rb +2 -0
  65. data/spec/delayed/server_spec.rb +2 -0
  66. data/spec/delayed/settings_spec.rb +2 -0
  67. data/spec/delayed/work_queue/in_process_spec.rb +2 -0
  68. data/spec/delayed/work_queue/parent_process/client_spec.rb +2 -0
  69. data/spec/delayed/work_queue/parent_process/server_spec.rb +2 -0
  70. data/spec/delayed/work_queue/parent_process_spec.rb +2 -0
  71. data/spec/delayed/worker/consul_health_check_spec.rb +2 -0
  72. data/spec/delayed/worker/health_check_spec.rb +2 -0
  73. data/spec/delayed/worker_spec.rb +2 -0
  74. data/spec/gemfiles/42.gemfile.lock +192 -0
  75. data/spec/gemfiles/50.gemfile.lock +197 -0
  76. data/spec/gemfiles/51.gemfile.lock +198 -0
  77. data/spec/gemfiles/52.gemfile.lock +206 -0
  78. data/spec/gemfiles/60.gemfile.lock +222 -0
  79. data/spec/migrate/20140924140513_add_story_table.rb +2 -0
  80. data/spec/redis_job_spec.rb +10 -8
  81. data/spec/sample_jobs.rb +2 -0
  82. data/spec/shared/delayed_batch.rb +17 -15
  83. data/spec/shared/delayed_method.rb +49 -204
  84. data/spec/shared/performable_method.rb +11 -9
  85. data/spec/shared/shared_backend.rb +27 -25
  86. data/spec/shared/testing.rb +7 -5
  87. data/spec/shared/worker.rb +15 -13
  88. data/spec/shared_jobs_specs.rb +2 -0
  89. data/spec/spec_helper.rb +3 -1
  90. metadata +17 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1547b62f3c5fd86703cc209ec4b0feb6954db3c6fb4b58f4bcdbcf58dc9a9eb
4
- data.tar.gz: 95ad1cacd71ac4511ee29eb0d3fda780037768234c232302b6fc10084de9e351
3
+ metadata.gz: 8c754ed71778d5b3f08641e133be947fae204a56dcee71aef08a7780a7d6afa5
4
+ data.tar.gz: 10949318e78e8e9d56b92ee7f2d14bfd647da20ff70578d894e4d1e85441d2fe
5
5
  SHA512:
6
- metadata.gz: bd27fc7e6c0ca5a613ba98ea0928d7947f2344d05c57ab14f588ff615c69bab60a0b6f08e60d1b610b6746ad8a467d151237f1469129f6144d5e93ce20ea71ef
7
- data.tar.gz: 25ce44b9f6eeedae9605c4bc2077a9e9b51a4b7df94ba4d68be1e78f70801af65273c332caba780c11bf523cff31daed9c44d8f068f697a8910781b09a2daf88
6
+ metadata.gz: 1a014e191bc0d6ccd083340b6d5c4bca0b7e03439aca459f79a5a704d93d16c42dd9e4855ca5985f7b1e4fb1fe62eead160cb6cb356c73b00ac297dc30112d8a
7
+ data.tar.gz: 53997c66017cf6db561104054379cb9e7e934fcc56c54d552b7629ff29eeb58de37c8674088661ba683e7e4d8b19234f26021819753ac06a6c738dd435c3f169
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CreateDelayedJobs < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddDelayedJobsTag < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddDelayedJobsMaxAttempts < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddDelayedJobsStrand < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CleanupDelayedJobsIndexes < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class OptimizeDelayedJobs < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddDelayedJobsNextInStrand < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DelayedJobsDeleteTriggerLockForUpdate < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DropPsqlJobsPopFn < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DelayedJobsUseAdvisoryLocks < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class IndexJobsOnLockedBy < ActiveRecord::Migration[4.2]
2
4
  disable_ddl_transaction! if respond_to?(:disable_ddl_transaction!)
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddJobsRunAtIndex < ActiveRecord::Migration[4.2]
2
4
  disable_ddl_transaction! if respond_to?(:disable_ddl_transaction!)
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ChangeDelayedJobsHandlerToText < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddFailedJobsOriginalJobId < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CopyFailedJobsOriginalId < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DropFailedJobsOriginalId < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Backend::ActiveRecord::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddSourceToJobs < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddMaxConcurrentToJobs < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddExpiresAtToJobs < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ImproveMaxConcurrent < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddBackDefaultStringLimitsJobs < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class SpeedUpMaxConcurrentTriggers < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class MakeCriticalColumnsNotNull < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddIdToGetDelayedJobsIndex < ActiveRecord::Migration[4.2]
2
4
  disable_ddl_transaction! if respond_to?(:disable_ddl_transaction!)
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class SpeedUpMaxConcurrentDeleteTrigger < ActiveRecord::Migration[4.2]
2
4
  def connection
3
5
  Delayed::Job.connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddStrandOrderOverride < ActiveRecord::Migration[4.2]
2
4
  disable_ddl_transaction! if respond_to?(:disable_ddl_transaction!)
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ActiveRecord::Base
2
4
  def self.load_for_delayed_job(id)
3
5
  if id
@@ -105,7 +107,7 @@ module Delayed
105
107
  # so rather than changing the strand and balancing at queue time,
106
108
  # this keeps the strand intact and uses triggers to limit the number running
107
109
  def self.n_strand_options(strand_name, num_strands)
108
- {:strand => strand_name, :max_concurrent => num_strands}
110
+ { strand: strand_name, max_concurrent: num_strands }
109
111
  end
110
112
 
111
113
  def self.current
@@ -125,8 +127,8 @@ module Delayed
125
127
  end
126
128
 
127
129
  # a nice stress test:
128
- # 10_000.times { |i| Kernel.send_later_enqueue_args(:system, { :strand => 's1', :run_at => (24.hours.ago + (rand(24.hours.to_i))) }, "echo #{i} >> test1.txt") }
129
- # 500.times { |i| "ohai".send_later_enqueue_args(:reverse, { :run_at => (12.hours.ago + (rand(24.hours.to_i))) }) }
130
+ # 10_000.times { |i| Kernel.delay(strand: 's1', run_at: (24.hours.ago + (rand(24.hours.to_i))).system("echo #{i} >> test1.txt") }
131
+ # 500.times { |i| "ohai".delay(run_at: (12.hours.ago + (rand(24.hours.to_i))).reverse }
130
132
  # then fire up your workers
131
133
  # you can check out strand correctness: diff test1.txt <(sort -n test1.txt)
132
134
  def self.ready_to_run(forced_latency: nil)
@@ -288,7 +290,7 @@ module Delayed
288
290
  lock(lock)
289
291
  jobs_with_row_number = all.from(target_jobs).
290
292
  select("id, ROW_NUMBER() OVER () AS row_number")
291
- updates = "locked_by = CASE row_number "
293
+ updates = +"locked_by = CASE row_number "
292
294
  effective_worker_names.each_with_index do |worker, i|
293
295
  updates << "WHEN #{i + 1} THEN #{connection.quote(worker)} "
294
296
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Delayed
2
4
  module Backend
3
5
  class DeserializationError < StandardError
@@ -28,19 +30,31 @@ module Delayed
28
30
  # The first argument should be an object that respond_to?(:perform)
29
31
  # The rest should be named arguments, these keys are expected:
30
32
  # :priority, :run_at, :queue, :strand, :singleton
31
- # Example: Delayed::Job.enqueue(object, :priority => 0, :run_at => time, :queue => queue)
32
- def enqueue(*args)
33
- object = args.shift
33
+ # Example: Delayed::Job.enqueue(object, priority: 0, run_at: time, queue: queue)
34
+ def enqueue(object,
35
+ priority: default_priority,
36
+ run_at: nil,
37
+ expires_at: nil,
38
+ queue: Delayed::Settings.queue,
39
+ strand: nil,
40
+ singleton: nil,
41
+ n_strand: nil,
42
+ max_attempts: Delayed::Settings.max_attempts,
43
+ **kwargs)
44
+
34
45
  unless object.respond_to?(:perform)
35
46
  raise ArgumentError, 'Cannot enqueue items which do not respond to perform'
36
47
  end
37
48
 
38
- options = Settings.default_job_options.merge(args.first || {})
39
- options[:priority] ||= self.default_priority
40
- options[:payload_object] = object
41
- options[:queue] = Delayed::Settings.queue unless options.key?(:queue)
42
- options[:max_attempts] ||= Delayed::Settings.max_attempts
43
- options[:source] = Marginalia::Comment.construct_comment if defined?(Marginalia) && Marginalia::Comment.components
49
+ kwargs = Settings.default_job_options.merge(kwargs)
50
+ kwargs[:payload_object] = object
51
+ kwargs[:priority] = priority
52
+ kwargs[:run_at] = run_at if run_at
53
+ kwargs[:strand] = strand
54
+ kwargs[:max_attempts] = max_attempts
55
+ kwargs[:source] = Marginalia::Comment.construct_comment if defined?(Marginalia) && Marginalia::Comment.components
56
+ kwargs[:expires_at] = expires_at
57
+ kwargs[:queue] = queue
44
58
 
45
59
  # If two parameters are given to n_strand, the first param is used
46
60
  # as the strand name for looking up the Setting, while the second
@@ -49,8 +63,8 @@ module Delayed
49
63
  # For instance, you can pass ["my_job_type", # root_account.global_id]
50
64
  # to get a set of n strands per root account, and you can apply the
51
65
  # same default to all.
52
- if options[:n_strand]
53
- strand_name, ext = options.delete(:n_strand)
66
+ if n_strand
67
+ strand_name, ext = n_strand
54
68
 
55
69
  if ext
56
70
  full_strand_name = "#{strand_name}/#{ext}"
@@ -62,18 +76,18 @@ module Delayed
62
76
  num_strands ||= Delayed::Settings.num_strands.call(strand_name)
63
77
  num_strands = num_strands ? num_strands.to_i : 1
64
78
 
65
- options.merge!(n_strand_options(full_strand_name, num_strands))
79
+ kwargs.merge!(n_strand_options(full_strand_name, num_strands))
66
80
  end
67
81
 
68
- if options[:singleton]
69
- options[:strand] = options.delete :singleton
70
- job = self.create_singleton(options)
71
- elsif batches && options.slice(:strand, :run_at).empty?
72
- batch_enqueue_args = options.slice(*self.batch_enqueue_args)
73
- batches[batch_enqueue_args] << options
82
+ if singleton
83
+ kwargs[:strand] = singleton
84
+ job = self.create_singleton(**kwargs)
85
+ elsif batches && strand.nil? && run_at.nil?
86
+ batch_enqueue_args = kwargs.slice(*self.batch_enqueue_args)
87
+ batches[batch_enqueue_args] << kwargs
74
88
  return true
75
89
  else
76
- job = self.create(options)
90
+ job = self.create(**kwargs)
77
91
  end
78
92
 
79
93
  JobTracking.job_created(job)
@@ -87,7 +101,7 @@ module Delayed
87
101
  def n_strand_options(strand_name, num_strands)
88
102
  strand_num = num_strands > 1 ? rand(num_strands) + 1 : 1
89
103
  strand_name += ":#{strand_num}" if strand_num > 1
90
- {:strand => strand_name}
104
+ { strand: strand_name }
91
105
  end
92
106
 
93
107
  def in_delayed_job?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'redis/scripting'
2
4
 
3
5
  # This module handles loading the Lua functions into Redis and running them
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This can't currently be made compatible with redis cluster, because the Lua functions
2
4
  # access keys that aren't in their keys argument list (since they pop jobs off
3
5
  # a queue and then update the job with that id).
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Delayed
2
4
  module Batch
3
5
  class PerformableBatch < Struct.new(:mode, :items)
@@ -18,7 +20,7 @@ module Delayed
18
20
  end
19
21
 
20
22
  def jobs
21
- items.map { |opts| Delayed::Job.new(opts) }
23
+ items.map { |opts| Delayed::Job.new(**opts) }
22
24
  end
23
25
  end
24
26
 
@@ -45,9 +47,9 @@ module Delayed
45
47
  elsif batch.size == 1
46
48
  args = batch.first.merge(batch_args)
47
49
  payload_object = args.delete(:payload_object)
48
- Delayed::Job.enqueue(payload_object, args)
50
+ Delayed::Job.enqueue(payload_object, **args)
49
51
  else
50
- Delayed::Job.enqueue(Delayed::Batch::PerformableBatch.new(mode, batch), enqueue_args.merge(batch_args))
52
+ Delayed::Job.enqueue(Delayed::Batch::PerformableBatch.new(mode, batch), **enqueue_args.merge(batch_args))
51
53
  end
52
54
  end
53
55
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optparse'
2
4
 
3
5
  module Delayed
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fileutils'
2
4
 
3
5
  module Delayed
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Delayed
2
4
  class Engine < ::Rails::Engine
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Delayed
2
4
  # Used when a block of code wants to track what jobs are created,
3
5
  # for instance in tests.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Delayed
2
4
  class InvalidCallback < Exception; end
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Delayed
2
4
  class LogTailer
3
5
  def run
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
 
3
5
  module Delayed
@@ -1,109 +1,67 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Delayed
2
4
  module MessageSending
3
- def send_later(method, *args)
4
- send_later_enqueue_args(method, {}, *args)
5
- end
6
-
7
- def send_later_enqueue_args(method, enqueue_args = {}, *args)
8
- enqueue_args = enqueue_args.dup
9
- # support procs/methods as enqueue arguments
10
- enqueue_args.each do |k,v|
11
- if v.respond_to?(:call)
12
- enqueue_args[k] = v.call(self)
13
- end
5
+ class DelayProxy < BasicObject
6
+ def initialize(object, enqueue_args)
7
+ @object = object
8
+ @enqueue_args = enqueue_args
14
9
  end
15
10
 
16
- no_delay = enqueue_args.delete(:no_delay)
17
- on_failure = enqueue_args.delete(:on_failure)
18
- on_permanent_failure = enqueue_args.delete(:on_permanent_failure)
19
- if !no_delay
20
- # delay queuing up the job in another database until the results of the current
21
- # transaction are visible
22
- connection = self.class.connection if self.class.respond_to?(:connection)
23
- connection ||= self.connection if respond_to?(:connection)
24
- connection ||= ActiveRecord::Base.connection
25
-
26
- if (Delayed::Job != Delayed::Backend::ActiveRecord::Job || connection != Delayed::Job.connection)
27
- connection.after_transaction_commit do
28
- Delayed::Job.enqueue(Delayed::PerformableMethod.new(self, method.to_sym, args,
29
- on_failure, on_permanent_failure), enqueue_args)
11
+ def method_missing(method, *args, **kwargs)
12
+ ignore_transaction = @enqueue_args.delete(:ignore_transaction)
13
+ on_failure = @enqueue_args.delete(:on_failure)
14
+ on_permanent_failure = @enqueue_args.delete(:on_permanent_failure)
15
+ if !ignore_transaction
16
+ # delay queuing up the job in another database until the results of the current
17
+ # transaction are visible
18
+ connection = @object.class.connection if @object.class.respond_to?(:connection)
19
+ connection ||= @object.connection if @object.respond_to?(:connection)
20
+ connection ||= ::ActiveRecord::Base.connection
21
+
22
+ if (::Delayed::Job != ::Delayed::Backend::ActiveRecord::Job || connection != ::Delayed::Job.connection)
23
+ connection.after_transaction_commit do
24
+ ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object, method,
25
+ args: args, kwargs: kwargs,
26
+ on_failure: on_failure,
27
+ on_permanent_failure: on_permanent_failure),
28
+ **@enqueue_args)
29
+ end
30
+ return nil
30
31
  end
31
- return nil
32
32
  end
33
- end
34
-
35
- result = Delayed::Job.enqueue(Delayed::PerformableMethod.new(self, method.to_sym, args,
36
- on_failure, on_permanent_failure), enqueue_args)
37
- result = nil unless no_delay
38
- result
39
- end
40
-
41
- def send_later_with_queue(method, queue, *args)
42
- send_later_enqueue_args(method, { :queue => queue }, *args)
43
- end
44
-
45
- def send_at(time, method, *args)
46
- send_later_enqueue_args(method,
47
- { :run_at => time }, *args)
48
- end
49
-
50
- def send_at_with_queue(time, method, queue, *args)
51
- send_later_enqueue_args(method,
52
- { :run_at => time, :queue => queue },
53
- *args)
54
- end
55
-
56
- def send_later_unless_in_job(method, *args)
57
- if Delayed::Job.in_delayed_job?
58
- send(method, *args)
59
- else
60
- send_later(method, *args)
61
- end
62
- nil # can't rely on the type of return value, so return nothing
63
- end
64
33
 
65
- def send_later_if_production(*args)
66
- if Rails.env.production?
67
- send_later(*args)
68
- else
69
- send(*args)
34
+ result = ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object, method,
35
+ args: args,
36
+ kwargs: kwargs,
37
+ on_failure: on_failure,
38
+ on_permanent_failure: on_permanent_failure),
39
+ **@enqueue_args)
40
+ result = nil unless ignore_transaction
41
+ result
70
42
  end
71
43
  end
72
44
 
73
- def send_later_if_production_enqueue_args(method, enqueue_args, *args)
74
- if Rails.env.production?
75
- send_later_enqueue_args(method, enqueue_args, *args)
76
- else
77
- send(method, *args)
78
- end
79
- end
80
-
81
- def send_now_or_later(_when, *args)
82
- if _when == :now
83
- send(*args)
84
- else
85
- send_later(*args)
45
+ def delay(**enqueue_args)
46
+ # support procs/methods as enqueue arguments
47
+ enqueue_args.each do |k,v|
48
+ if v.respond_to?(:call)
49
+ enqueue_args[k] = v.call(self)
50
+ end
86
51
  end
87
- end
88
-
89
- def send_now_or_later_if_production(_when, *args)
90
- if _when == :now
91
- send(*args)
92
- else
93
- send_later_if_production(*args)
52
+ if enqueue_args.delete(:synchronous)
53
+ return self
94
54
  end
55
+ DelayProxy.new(self, enqueue_args)
95
56
  end
96
57
 
97
58
  module ClassMethods
98
59
  KWARG_ARG_TYPES = %i{key keyreq keyrest}.freeze
99
60
  private_constant :KWARG_ARG_TYPES
100
61
 
101
- def add_send_later_methods(method_name, enqueue_args={}, default_async=false)
62
+ def handle_asynchronously(method_name, **enqueue_args)
102
63
  aliased_method, punctuation = method_name.to_s.sub(/([?!=])$/, ''), $1
103
64
 
104
- # we still need this for backwards compatibility
105
- without_method = "#{aliased_method}_without_send_later#{punctuation}"
106
-
107
65
  if public_method_defined?(method_name)
108
66
  visibility = :public
109
67
  elsif private_method_defined?(method_name)
@@ -114,49 +72,28 @@ module Delayed
114
72
 
115
73
  if has_kwargs? method_name
116
74
  generated_delayed_methods.class_eval do
117
- define_method without_method do |*args, **kwargs|
118
- send(method_name, *args, synchronous: true, **kwargs)
119
- end
120
-
121
- define_method(method_name, -> (*args, synchronous: !default_async, **kwargs) do
75
+ define_method(method_name, -> (*args, synchronous: false, **kwargs) do
122
76
  if synchronous
123
77
  super(*args, **kwargs)
124
78
  else
125
- send_later_enqueue_args(method_name, enqueue_args, *args, synchronous: true, **kwargs)
79
+ delay(**enqueue_args).method_missing(method_name, *args, synchronous: true, **kwargs)
126
80
  end
127
81
  end)
128
82
  end
129
83
  else
130
84
  generated_delayed_methods.class_eval do
131
- define_method without_method do |*args|
132
- send(method_name, *args, synchronous: true)
133
- end
134
-
135
- define_method(method_name, -> (*args, synchronous: !default_async) do
85
+ define_method(method_name, -> (*args, synchronous: false) do
136
86
  if synchronous
137
87
  super(*args)
138
88
  else
139
- send_later_enqueue_args(method_name, enqueue_args, *args, synchronous: true)
89
+ delay(**enqueue_args).method_missing(method_name, *args, synchronous: true)
140
90
  end
141
91
  end)
142
92
  end
143
93
  end
144
- generated_delayed_methods.send(visibility, without_method)
145
94
  generated_delayed_methods.send(visibility, method_name)
146
95
  end
147
96
 
148
- def handle_asynchronously(method, enqueue_args={})
149
- add_send_later_methods(method, enqueue_args, true)
150
- end
151
-
152
- def handle_asynchronously_with_queue(method, queue)
153
- add_send_later_methods(method, {:queue => queue}, true)
154
- end
155
-
156
- def handle_asynchronously_if_production(method, enqueue_args={})
157
- add_send_later_methods(method, enqueue_args, Rails.env.production?)
158
- end
159
-
160
97
  private
161
98
 
162
99
  def generated_delayed_methods