inst-jobs 0.15.22 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/db/migrate/20101216224513_create_delayed_jobs.rb +2 -0
- data/db/migrate/20110208031356_add_delayed_jobs_tag.rb +2 -0
- data/db/migrate/20110426161613_add_delayed_jobs_max_attempts.rb +2 -0
- data/db/migrate/20110516225834_add_delayed_jobs_strand.rb +2 -0
- data/db/migrate/20110531144916_cleanup_delayed_jobs_indexes.rb +2 -0
- data/db/migrate/20110610213249_optimize_delayed_jobs.rb +2 -0
- data/db/migrate/20110831210257_add_delayed_jobs_next_in_strand.rb +2 -0
- data/db/migrate/20120510004759_delayed_jobs_delete_trigger_lock_for_update.rb +2 -0
- data/db/migrate/20120531150712_drop_psql_jobs_pop_fn.rb +2 -0
- data/db/migrate/20120607164022_delayed_jobs_use_advisory_locks.rb +2 -0
- data/db/migrate/20120607181141_index_jobs_on_locked_by.rb +2 -0
- data/db/migrate/20120608191051_add_jobs_run_at_index.rb +2 -0
- data/db/migrate/20120927184213_change_delayed_jobs_handler_to_text.rb +2 -0
- data/db/migrate/20140505215131_add_failed_jobs_original_job_id.rb +2 -0
- data/db/migrate/20140505215510_copy_failed_jobs_original_id.rb +2 -0
- data/db/migrate/20140505223637_drop_failed_jobs_original_id.rb +2 -0
- data/db/migrate/20140512213941_add_source_to_jobs.rb +2 -0
- data/db/migrate/20150807133223_add_max_concurrent_to_jobs.rb +2 -0
- data/db/migrate/20151123210429_add_expires_at_to_jobs.rb +2 -0
- data/db/migrate/20151210162949_improve_max_concurrent.rb +2 -0
- data/db/migrate/20161206323555_add_back_default_string_limits_jobs.rb +2 -0
- data/db/migrate/20181217155351_speed_up_max_concurrent_triggers.rb +2 -0
- data/db/migrate/20190726154743_make_critical_columns_not_null.rb +2 -0
- data/db/migrate/20200330230722_add_id_to_get_delayed_jobs_index.rb +2 -0
- data/db/migrate/20200824222232_speed_up_max_concurrent_delete_trigger.rb +97 -0
- data/db/migrate/20200825011002_add_strand_order_override.rb +128 -0
- data/lib/delayed/backend/active_record.rb +9 -5
- data/lib/delayed/backend/base.rb +34 -20
- data/lib/delayed/backend/redis/functions.rb +2 -0
- data/lib/delayed/backend/redis/job.rb +2 -0
- data/lib/delayed/batch.rb +5 -3
- data/lib/delayed/cli.rb +2 -0
- data/lib/delayed/core_ext/kernel.rb +9 -0
- data/lib/delayed/daemon.rb +2 -0
- data/lib/delayed/engine.rb +2 -0
- data/lib/delayed/job_tracking.rb +2 -0
- data/lib/delayed/lifecycle.rb +2 -0
- data/lib/delayed/log_tailer.rb +2 -0
- data/lib/delayed/logging.rb +2 -0
- data/lib/delayed/message_sending.rb +90 -106
- data/lib/delayed/performable_method.rb +34 -6
- data/lib/delayed/periodic.rb +6 -4
- data/lib/delayed/plugin.rb +2 -0
- data/lib/delayed/pool.rb +2 -0
- data/lib/delayed/server.rb +2 -0
- data/lib/delayed/server/helpers.rb +2 -0
- data/lib/delayed/settings.rb +2 -0
- data/lib/delayed/testing.rb +2 -0
- data/lib/delayed/version.rb +3 -1
- data/lib/delayed/work_queue/in_process.rb +2 -0
- data/lib/delayed/work_queue/parent_process.rb +2 -0
- data/lib/delayed/work_queue/parent_process/client.rb +2 -0
- data/lib/delayed/work_queue/parent_process/server.rb +2 -0
- data/lib/delayed/worker.rb +2 -0
- data/lib/delayed/worker/consul_health_check.rb +3 -1
- data/lib/delayed/worker/health_check.rb +2 -0
- data/lib/delayed/worker/null_health_check.rb +2 -0
- data/lib/delayed/worker/process_helper.rb +2 -0
- data/lib/delayed/yaml_extensions.rb +2 -0
- data/lib/delayed_job.rb +4 -0
- data/lib/inst-jobs.rb +2 -0
- data/spec/active_record_job_spec.rb +4 -6
- data/spec/delayed/cli_spec.rb +2 -0
- data/spec/delayed/daemon_spec.rb +2 -0
- data/spec/delayed/message_sending_spec.rb +101 -0
- data/spec/delayed/server_spec.rb +2 -4
- data/spec/delayed/settings_spec.rb +2 -0
- data/spec/delayed/work_queue/in_process_spec.rb +2 -4
- data/spec/delayed/work_queue/parent_process/client_spec.rb +2 -4
- data/spec/delayed/work_queue/parent_process/server_spec.rb +2 -1
- data/spec/delayed/work_queue/parent_process_spec.rb +2 -1
- data/spec/delayed/worker/consul_health_check_spec.rb +3 -1
- data/spec/delayed/worker/health_check_spec.rb +2 -0
- data/spec/delayed/worker_spec.rb +2 -0
- data/spec/gemfiles/42.gemfile.lock +192 -0
- data/spec/gemfiles/50.gemfile.lock +197 -0
- data/spec/gemfiles/51.gemfile.lock +198 -0
- data/spec/gemfiles/52.gemfile.lock +206 -0
- data/spec/gemfiles/60.gemfile.lock +224 -0
- data/spec/migrate/20140924140513_add_story_table.rb +2 -0
- data/spec/redis_job_spec.rb +10 -12
- data/spec/sample_jobs.rb +2 -0
- data/spec/shared/delayed_batch.rb +17 -15
- data/spec/shared/delayed_method.rb +49 -204
- data/spec/shared/performable_method.rb +11 -9
- data/spec/shared/shared_backend.rb +27 -25
- data/spec/shared/testing.rb +7 -5
- data/spec/shared/worker.rb +15 -13
- data/spec/shared_jobs_specs.rb +2 -0
- data/spec/spec_helper.rb +12 -1
- metadata +36 -7
data/lib/delayed/backend/base.rb
CHANGED
@@ -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, :
|
32
|
-
def enqueue(
|
33
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
53
|
-
strand_name, ext =
|
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
|
-
|
79
|
+
kwargs.merge!(n_strand_options(full_strand_name, num_strands))
|
66
80
|
end
|
67
81
|
|
68
|
-
if
|
69
|
-
|
70
|
-
job = self.create_singleton(
|
71
|
-
elsif batches &&
|
72
|
-
batch_enqueue_args =
|
73
|
-
batches[batch_enqueue_args] <<
|
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(
|
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
|
-
{:
|
104
|
+
{ strand: strand_name }
|
91
105
|
end
|
92
106
|
|
93
107
|
def in_delayed_job?
|
data/lib/delayed/batch.rb
CHANGED
@@ -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
|
data/lib/delayed/cli.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
module Kernel
|
2
|
+
def sender(i = 0)
|
3
|
+
frame_self = nil
|
4
|
+
# 3. one for the block, one for this method, one for the method calling this
|
5
|
+
# method, and _then_ we get to the self for who sent the message we want
|
6
|
+
RubyVM::DebugInspector.open { |dc| frame_self = dc.frame_self(3 + i) }
|
7
|
+
frame_self
|
8
|
+
end
|
9
|
+
end
|
data/lib/delayed/daemon.rb
CHANGED
data/lib/delayed/engine.rb
CHANGED
data/lib/delayed/job_tracking.rb
CHANGED
data/lib/delayed/lifecycle.rb
CHANGED
data/lib/delayed/log_tailer.rb
CHANGED
data/lib/delayed/logging.rb
CHANGED
@@ -1,109 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if ::Rails.env.test? || ::Rails.env.development?
|
4
|
+
require 'debug_inspector'
|
5
|
+
end
|
6
|
+
|
1
7
|
module Delayed
|
2
8
|
module MessageSending
|
3
|
-
|
4
|
-
|
5
|
-
|
9
|
+
class DelayProxy < BasicObject
|
10
|
+
def initialize(object, synchronous: false, sender: nil, **enqueue_args)
|
11
|
+
@object = object
|
12
|
+
@enqueue_args = enqueue_args
|
13
|
+
@synchronous = synchronous
|
14
|
+
@sender = sender
|
15
|
+
end
|
6
16
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
17
|
+
def method_missing(method, *args, **kwargs)
|
18
|
+
# method doesn't exist? must be method_missing; assume private access
|
19
|
+
@sender = nil if !@sender.nil? &&
|
20
|
+
!@object.methods.include?(method) &&
|
21
|
+
!@object.protected_methods.include?(method) &&
|
22
|
+
!@object.private_methods.include?(method)
|
23
|
+
|
24
|
+
sender_is_object = @sender == @object
|
25
|
+
sender_is_class = @sender.is_a?(@object.class)
|
26
|
+
|
27
|
+
# even if the call is async, if the call is _going_ to generate an error, we make it synchronous
|
28
|
+
# so that the error is generated immediately, instead of waiting for it to fail in a job,
|
29
|
+
# which might go unnoticed
|
30
|
+
if !@sender.nil? && !@synchronous
|
31
|
+
@synchronous = true if !sender_is_object && @object.private_methods.include?(method)
|
32
|
+
@synchronous = true if !sender_is_class && @object.protected_methods.include?(method)
|
13
33
|
end
|
14
|
-
end
|
15
34
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
on_failure, on_permanent_failure), enqueue_args)
|
35
|
+
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)
|
30
48
|
end
|
31
|
-
return nil
|
32
49
|
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
50
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
ignore_transaction = @enqueue_args.delete(:ignore_transaction)
|
52
|
+
on_failure = @enqueue_args.delete(:on_failure)
|
53
|
+
on_permanent_failure = @enqueue_args.delete(:on_permanent_failure)
|
54
|
+
if !ignore_transaction
|
55
|
+
# delay queuing up the job in another database until the results of the current
|
56
|
+
# transaction are visible
|
57
|
+
connection = @object.class.connection if @object.class.respond_to?(:connection)
|
58
|
+
connection ||= @object.connection if @object.respond_to?(:connection)
|
59
|
+
connection ||= ::ActiveRecord::Base.connection
|
60
|
+
|
61
|
+
if (::Delayed::Job != ::Delayed::Backend::ActiveRecord::Job || connection != ::Delayed::Job.connection)
|
62
|
+
connection.after_transaction_commit do
|
63
|
+
::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)
|
69
|
+
end
|
70
|
+
return nil
|
71
|
+
end
|
72
|
+
end
|
55
73
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
74
|
+
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)
|
81
|
+
result = nil unless ignore_transaction
|
82
|
+
result
|
61
83
|
end
|
62
|
-
nil # can't rely on the type of return value, so return nothing
|
63
84
|
end
|
64
85
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
86
|
+
def delay(sender: nil, **enqueue_args)
|
87
|
+
# 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
|
70
92
|
end
|
71
|
-
end
|
72
93
|
|
73
|
-
|
74
|
-
if Rails.env.production?
|
75
|
-
send_later_enqueue_args(method, enqueue_args, *args)
|
76
|
-
else
|
77
|
-
send(method, *args)
|
78
|
-
end
|
79
|
-
end
|
94
|
+
sender ||= __calculate_sender_for_delay
|
80
95
|
|
81
|
-
|
82
|
-
if _when == :now
|
83
|
-
send(*args)
|
84
|
-
else
|
85
|
-
send_later(*args)
|
86
|
-
end
|
96
|
+
DelayProxy.new(self, sender: sender, **enqueue_args)
|
87
97
|
end
|
88
98
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
send_later_if_production(*args)
|
94
|
-
end
|
99
|
+
def __calculate_sender_for_delay
|
100
|
+
# enforce public send in dev and test, but not prod (since it uses
|
101
|
+
# debug APIs, it's expensive)
|
102
|
+
return sender(1) if ::Rails.env.test? || ::Rails.env.development?
|
95
103
|
end
|
96
104
|
|
97
105
|
module ClassMethods
|
98
106
|
KWARG_ARG_TYPES = %i{key keyreq keyrest}.freeze
|
99
107
|
private_constant :KWARG_ARG_TYPES
|
100
108
|
|
101
|
-
def
|
109
|
+
def handle_asynchronously(method_name, **enqueue_args)
|
102
110
|
aliased_method, punctuation = method_name.to_s.sub(/([?!=])$/, ''), $1
|
103
111
|
|
104
|
-
# we still need this for backwards compatibility
|
105
|
-
without_method = "#{aliased_method}_without_send_later#{punctuation}"
|
106
|
-
|
107
112
|
if public_method_defined?(method_name)
|
108
113
|
visibility = :public
|
109
114
|
elsif private_method_defined?(method_name)
|
@@ -114,49 +119,28 @@ module Delayed
|
|
114
119
|
|
115
120
|
if has_kwargs? method_name
|
116
121
|
generated_delayed_methods.class_eval do
|
117
|
-
define_method
|
118
|
-
send(method_name, *args, synchronous: true, **kwargs)
|
119
|
-
end
|
120
|
-
|
121
|
-
define_method(method_name, -> (*args, synchronous: !default_async, **kwargs) do
|
122
|
+
define_method(method_name, -> (*args, synchronous: false, **kwargs) do
|
122
123
|
if synchronous
|
123
124
|
super(*args, **kwargs)
|
124
125
|
else
|
125
|
-
|
126
|
+
delay(sender: __calculate_sender_for_delay, **enqueue_args).method_missing(method_name, *args, synchronous: true, **kwargs)
|
126
127
|
end
|
127
128
|
end)
|
128
129
|
end
|
129
130
|
else
|
130
131
|
generated_delayed_methods.class_eval do
|
131
|
-
define_method
|
132
|
-
send(method_name, *args, synchronous: true)
|
133
|
-
end
|
134
|
-
|
135
|
-
define_method(method_name, -> (*args, synchronous: !default_async) do
|
132
|
+
define_method(method_name, -> (*args, synchronous: false) do
|
136
133
|
if synchronous
|
137
134
|
super(*args)
|
138
135
|
else
|
139
|
-
|
136
|
+
delay(**enqueue_args).method_missing(method_name, *args, synchronous: true)
|
140
137
|
end
|
141
138
|
end)
|
142
139
|
end
|
143
140
|
end
|
144
|
-
generated_delayed_methods.send(visibility, without_method)
|
145
141
|
generated_delayed_methods.send(visibility, method_name)
|
146
142
|
end
|
147
143
|
|
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
144
|
private
|
161
145
|
|
162
146
|
def generated_delayed_methods
|
@@ -1,13 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Delayed
|
2
|
-
class PerformableMethod < Struct.new(:object, :method, :args, :fail_cb, :permanent_fail_cb)
|
3
|
-
def initialize(object, method, args
|
4
|
+
class PerformableMethod < Struct.new(:object, :method, :args, :kwargs, :fail_cb, :permanent_fail_cb, :sender)
|
5
|
+
def initialize(object, method, args: [], kwargs: {}, on_failure: nil, on_permanent_failure: nil, sender: nil)
|
4
6
|
raise NoMethodError, "undefined method `#{method}' for #{object.inspect}" unless object.respond_to?(method, true)
|
5
7
|
|
6
8
|
self.object = object
|
7
9
|
self.args = args
|
10
|
+
self.kwargs = kwargs
|
8
11
|
self.method = method.to_sym
|
9
|
-
self.fail_cb =
|
10
|
-
self.permanent_fail_cb =
|
12
|
+
self.fail_cb = on_failure
|
13
|
+
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
|
11
21
|
end
|
12
22
|
|
13
23
|
def display_name
|
@@ -20,7 +30,24 @@ module Delayed
|
|
20
30
|
alias_method :tag, :display_name
|
21
31
|
|
22
32
|
def perform
|
23
|
-
|
33
|
+
kwargs = self.kwargs || {}
|
34
|
+
|
35
|
+
sender_is_object = sender == object
|
36
|
+
sender_is_class = sender.is_a?(object.class)
|
37
|
+
|
38
|
+
if sender.nil? || sender_is_object || sender_is_class && object.protected_methods.include?(method)
|
39
|
+
if kwargs.empty?
|
40
|
+
object.send(method, *args)
|
41
|
+
else
|
42
|
+
object.send(method, *args, **kwargs)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
if kwargs.empty?
|
46
|
+
object.public_send(method, *args)
|
47
|
+
else
|
48
|
+
object.public_send(method, *args, **kwargs)
|
49
|
+
end
|
50
|
+
end
|
24
51
|
end
|
25
52
|
|
26
53
|
def on_failure(error)
|
@@ -46,7 +73,8 @@ module Delayed
|
|
46
73
|
|
47
74
|
def full_name
|
48
75
|
obj_name = object.is_a?(ActiveRecord::Base) ? "#{object.class}.find(#{object.id}).#{method}" : display_name
|
49
|
-
|
76
|
+
kwargs_str = kwargs.map { |(k, v)| ", #{k}: #{deep_de_ar_ize(v)}"}.join("")
|
77
|
+
"#{obj_name}(#{args.map { |a| deep_de_ar_ize(a) }.join(', ')}#{kwargs_str})"
|
50
78
|
end
|
51
79
|
end
|
52
80
|
end
|