class Async::Task
def defer_stop
@yields {} The block of code to execute.
If stop is invoked a second time, it will be immediately executed.
You can nest calls to defer_stop, but the stop will only be deferred until the outermost block exits.
Defer the handling of stop. During the execution of the given block, if a stop is requested, it will be deferred until the block exits. This is useful for ensuring graceful shutdown of servers and other long-running tasks. You should wrap the response handling code in a defer_stop block to ensure that the task is stopped when the response is complete but not before.
def defer_stop # Tri-state variable for controlling stop: # - nil: defer_stop has not been called. # - false: defer_stop has been called and we are not stopping. # - true: defer_stop has been called and we will stop when exiting the block. if @defer_stop.nil? begin # If we are not deferring stop already, we can defer it now: @defer_stop = false yield rescue Stop # If we are exiting due to a stop, we shouldn't try to invoke stop again: @defer_stop = nil raise ensure defer_stop = @defer_stop # We need to ensure the state is reset before we exit the block: @defer_stop = nil # If we were asked to stop, we should do so now: if defer_stop raise Stop, "Stopping current task (was deferred)!" end end else # If we are deferring stop already, entering it again is a no-op. yield end end