2021-11-16 10:15:14 -08:00
require " securerandom "
require " time "
module Sidekiq
module JobUtil
# These functions encapsulate various job utilities.
2022-05-06 13:52:38 -07:00
TRANSIENT_ATTRIBUTES = %w[ ]
2021-11-16 10:15:14 -08:00
def validate ( item )
raise ( ArgumentError , " Job must be a Hash with 'class' and 'args' keys: ` #{ item } ` " ) unless item . is_a? ( Hash ) && item . key? ( " class " ) && item . key? ( " args " )
raise ( ArgumentError , " Job args must be an Array: ` #{ item } ` " ) unless item [ " args " ] . is_a? ( Array )
raise ( ArgumentError , " Job class must be either a Class or String representation of the class name: ` #{ item } ` " ) unless item [ " class " ] . is_a? ( Class ) || item [ " class " ] . is_a? ( String )
raise ( ArgumentError , " Job 'at' must be a Numeric timestamp: ` #{ item } ` " ) if item . key? ( " at " ) && ! item [ " at " ] . is_a? ( Numeric )
raise ( ArgumentError , " Job tags must be an Array: ` #{ item } ` " ) if item [ " tags " ] && ! item [ " tags " ] . is_a? ( Array )
2022-03-17 10:42:33 -07:00
end
2021-12-07 13:20:20 -08:00
2022-03-17 10:42:33 -07:00
def verify_json ( item )
2022-03-09 11:36:32 -08:00
job_class = item [ " wrapped " ] || item [ " class " ]
2022-05-31 13:37:31 -07:00
if Sidekiq [ :on_complex_arguments ] == :raise
2021-12-07 13:20:20 -08:00
msg = << ~ EOM
2022-03-09 11:36:32 -08:00
Job arguments to #{job_class} must be native JSON types, see https://github.com/mperham/sidekiq/wiki/Best-Practices.
2022-05-13 14:56:26 -07:00
To disable this error , add ` Sidekiq.strict_args!(false) ` to your initializer .
2021-12-07 13:20:20 -08:00
EOM
2021-12-07 13:58:04 -08:00
raise ( ArgumentError , msg ) unless json_safe? ( item )
2022-05-31 13:37:31 -07:00
elsif Sidekiq [ :on_complex_arguments ] == :warn
2021-12-07 13:58:04 -08:00
Sidekiq . logger . warn << ~ EOM unless json_safe? ( item )
2022-03-09 11:36:32 -08:00
Job arguments to #{job_class} do not serialize to JSON safely. This will raise an error in
2021-12-07 13:58:04 -08:00
Sidekiq 7 . 0 . See https : / / github . com / mperham / sidekiq / wiki / Best - Practices or raise an error today
2022-01-05 19:54:12 -08:00
by calling ` Sidekiq.strict_args! ` during Sidekiq initialization .
2021-12-07 13:20:20 -08:00
EOM
end
2021-11-16 10:15:14 -08:00
end
def normalize_item ( item )
validate ( item )
# merge in the default sidekiq_options for the item's class and/or wrapped element
# this allows ActiveJobs to control sidekiq_options too.
defaults = normalized_hash ( item [ " class " ] )
2022-01-05 21:01:32 -08:00
defaults = defaults . merge ( item [ " wrapped " ] . get_sidekiq_options ) if item [ " wrapped " ] . respond_to? ( :get_sidekiq_options )
2021-11-16 10:15:14 -08:00
item = defaults . merge ( item )
raise ( ArgumentError , " Job must include a valid queue name " ) if item [ " queue " ] . nil? || item [ " queue " ] == " "
2022-05-06 13:52:38 -07:00
# remove job attributes which aren't necessary to persist into Redis
TRANSIENT_ATTRIBUTES . each { | key | item . delete ( key ) }
2022-03-14 12:16:15 -07:00
item [ " jid " ] || = SecureRandom . hex ( 12 )
2021-11-16 10:15:14 -08:00
item [ " class " ] = item [ " class " ] . to_s
item [ " queue " ] = item [ " queue " ] . to_s
item [ " created_at " ] || = Time . now . to_f
item
end
def normalized_hash ( item_class )
if item_class . is_a? ( Class )
2022-03-03 12:37:25 -08:00
raise ( ArgumentError , " Message must include a Sidekiq::Job class, not class name: #{ item_class . ancestors . inspect } " ) unless item_class . respond_to? ( :get_sidekiq_options )
2021-11-16 10:15:14 -08:00
item_class . get_sidekiq_options
else
2022-03-03 12:37:25 -08:00
Sidekiq . default_job_options
2021-11-16 10:15:14 -08:00
end
end
2021-12-07 13:20:20 -08:00
private
def json_safe? ( item )
2021-12-07 13:58:04 -08:00
JSON . parse ( JSON . dump ( item [ " args " ] ) ) == item [ " args " ]
2021-12-07 13:20:20 -08:00
end
2021-11-16 10:15:14 -08:00
end
end