class Resque::Plugins::Approve::PendingJob
A class representing a Pending job that is awaiting approval.
Each job has the following values:
id - The approve gem ID used to store and restore the job in Redis class_name - The name of the job class to be enqueued args - The arguments for the job to be enqueued requires_approval - If a class defines a default approval queue (similar to defining the queue for Resque), then instead of passing `approval_key: "key name"` in the parameters, you would pass `requires_approval: true`. This way the key name appears only in the class and not scattered through the code. approval_key - The approval key for the pending job that will be used to release/approve the job. This will default to nil. approval_queue - The queue that the pending job will be enqueued into. This will default to the queue for the job. approval_at - The time when the job is to be enqueued. This will call `enqueue_at` to enqueue the job, so this option will only work properly if you use the `resque-scheduler` gem. When using resque-scheduler, there are two ways to delay enqueue a job and how you do this depends on your use case. Resque.enqueue YourJob, params, approval_key: "your key", approval_at: time This will enqueue the job for approval, which will pause the job until it is approved. Once approved, the job will delay enqueue for time, and will execute immediately or at that time depending on if the time has passed. This is the recommended method to use as it will not run the job early, and it will allow you to release it without knowing if it is still delayed or not. You can also do: Resque.enqueue_at time, YourJob, params, approval_key: "your key" This will delay enqueue the job - because it has not been enqueued yet, the job cannot be releaed until the time has passed and the job is actually enqueued. Any time after that point, it can be released. Releasing the key before this time has no effect on this job.
Attributes
id[R]
Public Class Methods
new(id = SecureRandom.uuid, class_name: nil, args: [])
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 50 def initialize(id = SecureRandom.uuid, class_name: nil, args: []) @approve_options = {} @id = id @class_name = class_name.is_a?(String) ? class_name : class_name&.name self.args = args end
Public Instance Methods
<=>(other)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 57 def <=>(other) return nil unless other.is_a?(Resque::Plugins::Approve::PendingJob) id <=> other.id end
approval_at()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 128 def approval_at @approval_at ||= approve_options[:approval_at]&.to_time end
approval_key()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 105 def approval_key @approval_key ||= approve_options[:approval_key] end
approval_keys?()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 97 def approval_keys? @approval_keys ||= (approve_options.key?(:approval_key) || approve_options[:requires_approval]) end
approval_queue()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 109 def approval_queue @approval_queue ||= approve_options[:approval_queue] || Resque.queue_from_class(klass) end
approve_options()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 89 def approve_options @approve_options = if @approve_options.present? @approve_options else (decode_args(stored_values[:approve_options])&.first || {}).with_indifferent_access end end
args()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 71 def args @args = if @args.present? @args else Array.wrap(decode_args(stored_values[:args])) end end
args=(value)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 79 def args=(value) if value.nil? @args = [] else @args = Array.wrap(value).dup extract_approve_options end end
class_name()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 63 def class_name @class_name ||= stored_values[:class_name] end
compressable?()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 192 def compressable? !described_class.blank? && described_class.singleton_class.included_modules.map(&:name).include?("Resque::Plugins::Compressible") end
compressed?(basic_args)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 186 def compressed?(basic_args) return false unless compressable? described_class.compressed?(basic_args) end
delete()
click to toggle source
rubocop:enable Metrics/AbcSize
# File lib/resque/plugins/approve/pending_job.rb, line 158 def delete # Make sure the job is loaded into memory so we can use it even though we are going to delete it. stored_values redis.del(job_key) return if class_name.blank? queue.remove_job(self) end
enqueue_job()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 136 def enqueue_job return_value = if approval_at.present? Resque.enqueue_at_with_queue approval_queue, approval_at, klass, *compressed_args(args) else Resque.enqueue_to approval_queue, klass, *compressed_args(args) end delete return_value end
max_active_jobs()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 119 def max_active_jobs max_val = ((klass.respond_to?(:max_active_jobs) && klass.max_active_jobs) || (klass.instance_variable_defined?(:@max_active_jobs) && klass.instance_variable_get(:@max_active_jobs))) return -1 if max_val.blank? max_val.to_i end
max_active_jobs?()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 113 def max_active_jobs? return @max_active_jobs if defined?(@max_active_jobs) @max_active_jobs = max_active_jobs.positive? end
max_jobs_perform_args(args)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 173 def max_jobs_perform_args(args) return compressed_max_jobs_perform_args(args) if compressed?(args) return unless args.last.is_a?(Hash) remove_options = args[-1] %i[approval_queue approval_at requires_approval].each do |key| remove_options.delete(key) remove_options.delete(key.to_s) end end
queue()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 169 def queue @queue ||= Resque::Plugins::Approve::PendingJobQueue.new(approval_key) end
queue_time()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 132 def queue_time @queue_time ||= stored_values[:queue_time]&.to_time end
requires_approval?()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 101 def requires_approval? @requires_approval ||= approval_keys? && too_many_running? end
save!()
click to toggle source
rubocop:disable Metrics/AbcSize
# File lib/resque/plugins/approve/pending_job.rb, line 149 def save! redis.hset(job_key, "class_name", class_name) redis.hset(job_key, "args", encode_args(*args)) redis.hset(job_key, "approve_options", encode_args(approve_options)) redis.hset(job_key, "queue_time", Time.now) end
uncompressed_args()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 67 def uncompressed_args decompress_args(args) end
Private Instance Methods
approve_options=(value)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 257 def approve_options=(value) @approve_options = (value&.dup || {}).with_indifferent_access end
compressed_args(compress_args)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 296 def compressed_args(compress_args) return compress_args unless compressable? return compress_args if described_class.compressed?(compress_args) [{ :resque_compressed => true, :payload => described_class.compressed_args(compress_args) }] end
compressed_max_jobs_perform_args(args)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 199 def compressed_max_jobs_perform_args(args) decompressed = decompress_args(args) max_jobs_perform_args(decompressed) decompressed = compressed_args(decompressed)[0] compress_arg = args[0] compress_arg[:payload] = decompressed[:payload] if compress_arg.key?(:payload) compress_arg["payload"] = decompressed[:payload] if compress_arg.key?("payload") end
decode_args(args_string)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 251 def decode_args(args_string) return if args_string.blank? Resque.decode(args_string) end
decompress_args(basic_args)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 303 def decompress_args(basic_args) return basic_args unless compressable? return basic_args unless described_class.compressed?(basic_args) described_class.uncompressed_args(basic_args.first[:payload] || basic_args.first["payload"]) end
described_class()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 288 def described_class return if class_name.blank? class_name.constantize rescue StandardError nil end
encode_args(*args)
click to toggle source
rubocop:enable Layout/SpaceAroundOperators
# File lib/resque/plugins/approve/pending_job.rb, line 247 def encode_args(*args) Resque.encode(args) end
extract_approve_options()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 222 def extract_approve_options extract_args = uncompressed_args return if extract_args.blank? || !extract_args[-1].is_a?(Hash) self.approve_options = extract_args.pop.with_indifferent_access options = slice_approval_options extract_args << options.to_hash if options.present? @args = compressed_args(extract_args) end
job_key()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 214 def job_key @job_key ||= "approve.pending_job.#{id}" end
klass()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 210 def klass @klass ||= class_name.constantize end
options_approval_key(options)
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 273 def options_approval_key(options) return unless max_active_jobs? return if options.key?(:approval_key) if compressable? unless klass.singleton_class.included_modules.include?(Resque::Plugins::Approve::CompressableAutoApproveNext) klass.extend Resque::Plugins::Approve::CompressableAutoApproveNext end else klass.include Resque::Plugins::Approve::AutoApproveNext unless klass.included_modules.include?(Resque::Plugins::Approve::AutoApproveNext) end options[:approval_key] = approve_options.fetch(:approval_key) { klass.default_queue_name } end
slice_approval_options()
click to toggle source
rubocop:disable Layout/SpaceAroundOperators
# File lib/resque/plugins/approve/pending_job.rb, line 236 def slice_approval_options options = approve_options.slice!(:approval_key, :approval_queue, :approval_at, :requires_approval) approve_options[:approval_key] ||= klass.default_queue_name if approve_options[:requires_approval] options_approval_key(options) options end
stored_values()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 218 def stored_values @stored_values ||= (redis.hgetall(job_key) || {}).with_indifferent_access end
too_many_running?()
click to toggle source
# File lib/resque/plugins/approve/pending_job.rb, line 261 def too_many_running? return true if queue.paused? return true unless max_active_jobs? return @too_many_running if defined?(@too_many_running) num_running = queue.increment_running max_jobs = max_active_jobs queue.decrement_running if num_running > max_jobs @too_many_running = num_running > max_jobs end