class ActiveSupport::ExecutionWrapper
def self.active? # :nodoc:
def self.active? # :nodoc: @active[Thread.current] end
def self.inherited(other) # :nodoc:
def self.inherited(other) # :nodoc: super other.active = Concurrent::Hash.new end
def self.register_hook(hook, outer: false)
a preceding +to_run+ block; all ordinary +to_complete+ blocks are
(Mostly, this means it won't be invoked if an exception occurs in
and will only be invoked if +run+ has previously been called.
+hook.complete+ will be passed the value returned from +hook.run+,
+complete+ steps.
Register an object to be invoked during both the +run+ and
def self.register_hook(hook, outer: false) if outer to_run RunHook.new(hook), prepend: true to_complete :after, CompleteHook.new(hook) else to_run RunHook.new(hook) to_complete CompleteHook.new(hook) end end
def self.run!
after the work has been performed.
Returns an instance, whose +complete!+ method *must* be invoked
Run this execution.
def self.run! if active? Null else new.tap do |instance| success = nil begin instance.run! success = true ensure instance.complete! unless success end end end end
def self.to_complete(*args, &block)
def self.to_complete(*args, &block) set_callback(:complete, *args, &block) end
def self.to_run(*args, &block)
def self.to_run(*args, &block) set_callback(:run, *args, &block) end
def self.wrap
def self.wrap return yield if active? instance = run! begin yield ensure instance.complete! end end
def complete!
exactly once on the result of any call to +run!+.
Complete this in-flight execution. This method *must* be called
def complete! run_callbacks(:complete) ensure self.class.active.delete Thread.current end
def hook_state
def hook_state @_hook_state ||= {} end
def run! # :nodoc:
def run! # :nodoc: self.class.active[Thread.current] = true run_callbacks(:run) end