2021-11-16 13:15:14 -05:00
require " securerandom "
require " time "
module Sidekiq
module JobUtil
# These functions encapsulate various job utilities.
2022-05-06 16:52:38 -04:00
TRANSIENT_ATTRIBUTES = %w[ ]
2021-11-16 13:15:14 -05: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 13:42:33 -04:00
end
2021-12-07 16:20:20 -05:00
2022-03-17 13:42:33 -04:00
def verify_json ( item )
2022-03-09 14:36:32 -05:00
job_class = item [ " wrapped " ] || item [ " class " ]
2022-05-31 16:37:31 -04:00
if Sidekiq [ :on_complex_arguments ] == :raise
2021-12-07 16:20:20 -05:00
msg = << ~ EOM
2022-03-09 14:36:32 -05:00
Job arguments to #{job_class} must be native JSON types, see https://github.com/mperham/sidekiq/wiki/Best-Practices.
2022-01-05 22:54:12 -05:00
To disable this error , remove ` Sidekiq.strict_args! ` from your initializer .
2021-12-07 16:20:20 -05:00
EOM
2021-12-07 16:58:04 -05:00
raise ( ArgumentError , msg ) unless json_safe? ( item )
2022-05-31 16:37:31 -04:00
elsif Sidekiq [ :on_complex_arguments ] == :warn
2021-12-07 16:58:04 -05:00
Sidekiq . logger . warn << ~ EOM unless json_safe? ( item )
2022-03-09 14:36:32 -05:00
Job arguments to #{job_class} do not serialize to JSON safely. This will raise an error in
2021-12-07 16:58:04 -05:00
Sidekiq 7 . 0 . See https : / / github . com / mperham / sidekiq / wiki / Best - Practices or raise an error today
2022-01-05 22:54:12 -05:00
by calling ` Sidekiq.strict_args! ` during Sidekiq initialization .
2021-12-07 16:20:20 -05:00
EOM
end
2021-11-16 13:15:14 -05: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-06 00:01:32 -05:00
defaults = defaults . merge ( item [ " wrapped " ] . get_sidekiq_options ) if item [ " wrapped " ] . respond_to? ( :get_sidekiq_options )
2021-11-16 13:15:14 -05:00
item = defaults . merge ( item )
raise ( ArgumentError , " Job must include a valid queue name " ) if item [ " queue " ] . nil? || item [ " queue " ] == " "
2022-05-06 16:52:38 -04:00
# remove job attributes which aren't necessary to persist into Redis
TRANSIENT_ATTRIBUTES . each { | key | item . delete ( key ) }
2022-03-14 15:16:15 -04:00
item [ " jid " ] || = SecureRandom . hex ( 12 )
2021-11-16 13:15:14 -05: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 15:37:25 -05: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 13:15:14 -05:00
item_class . get_sidekiq_options
else
2022-03-03 15:37:25 -05:00
Sidekiq . default_job_options
2021-11-16 13:15:14 -05:00
end
end
2021-12-07 16:20:20 -05:00
private
def json_safe? ( item )
2021-12-07 16:58:04 -05:00
JSON . parse ( JSON . dump ( item [ " args " ] ) ) == item [ " args " ]
2021-12-07 16:20:20 -05:00
end
2021-11-16 13:15:14 -05:00
end
end