fatkodima / sidekiq-iteration

Make your long-running sidekiq jobs interruptible and resumable.
https://rubydoc.info/gems/sidekiq-iteration
MIT License
270 stars 8 forks source link

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

Closed calvincchen closed 8 months ago

calvincchen commented 9 months ago

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!

fatkodima commented 8 months ago

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 https://github.com/fatkodima/sidekiq-iteration/blob/a1b531353cacb050b7f9d3b67abab3eacb73b1fe/lib/sidekiq_iteration/iteration.rb#L22-L25 https://github.com/fatkodima/sidekiq-iteration/blob/a1b531353cacb050b7f9d3b67abab3eacb73b1fe/lib/sidekiq_iteration/iteration.rb#L185-L190

Hope this helps.

calvincchen commented 8 months ago

Yeah, that cleared up so much. Thanks!