fatkodima/sidekiq-iteration

[Question] What calls `throw(:abort)`

calvincchen opened this issue · 2 comments

Hi,

I'm trying to better understand how sidekiq-iteration works and which signals lead to resumable jobs. I believe the key logic is here. My understanding is that a corresponding throw(:abort) is necessary to exit the block early, but I wasn't able to find any references in sidekiq or sidekiq-iteration? Looking at sidekiq, UNIX signals are transformed into raise Interrupt (link). I haven't been able to find the connection between this raise Interrupt and catch(:abort) and was hoping for some clarification.

Thanks!

So firstly, catch(:abort) do will return not only when someone calls throw :abort, but also when the corresponding block completes its execution.

My understanding is that a corresponding throw(:abort) is necessary to exit the block early

Yeah, this is not documented yet, but when you write something like

class MyJob
  def each_iteration(object)
   if some_condition?
     throw :abort
   else
     # do normal work
  end
end

then this job will be prematurely aborted without further retries. This is the only place where throw :abort is expected to be raised.

Looking at sidekiq, UNIX signals are transformed into raise Interrupt (link). I haven't been able to find the connection between this raise Interrupt and catch(:abort) and was hoping for some clarification.

Yeah, these are raised/rescued and transformed into other errors in sidekiq itself internally
https://github.com/sidekiq/sidekiq/blob/312672deab31c23810a272d1b06c33c84afaf9dd/bin/sidekiq#L31
https://github.com/sidekiq/sidekiq/blob/312672deab31c23810a272d1b06c33c84afaf9dd/lib/sidekiq/cli.rb#L113
https://github.com/sidekiq/sidekiq/blob/312672deab31c23810a272d1b06c33c84afaf9dd/lib/sidekiq/cli.rb#L130-L140
https://github.com/sidekiq/sidekiq/blob/312672deab31c23810a272d1b06c33c84afaf9dd/lib/sidekiq/launcher.rb#L61-L65
https://github.com/sidekiq/sidekiq/blob/312672deab31c23810a272d1b06c33c84afaf9dd/lib/sidekiq/manager.rb#L52-L65
https://github.com/sidekiq/sidekiq/blob/312672deab31c23810a272d1b06c33c84afaf9dd/lib/sidekiq/manager.rb#L44-L50
https://github.com/sidekiq/sidekiq/blob/312672deab31c23810a272d1b06c33c84afaf9dd/lib/sidekiq/processor.rb#L43-L47

When this happens, sidekiq-iteration detects that sidekiq is stopping and requeues itself, see

throttle_on(backoff: SidekiqIteration.default_retry_backoff) do
defined?(Sidekiq::CLI) &&
Sidekiq::CLI.instance.launcher.stopping?
end

throttle_condition = find_throttle_condition
if throttle_condition
@job_iteration_retry_backoff = throttle_condition.backoff
@needs_reenqueue = true
return false
end

Hope this helps.

Yeah, that cleared up so much. Thanks!