diff options
author | Matthew Draper <matthew@trebex.net> | 2016-04-05 06:11:28 +0930 |
---|---|---|
committer | Matthew Draper <matthew@trebex.net> | 2016-04-05 06:57:01 +0930 |
commit | 291a098c111ff419506094e14c0186389b0020ca (patch) | |
tree | 314ffa2a9fe18d130bdd929afe6350abc8539841 /activesupport/lib | |
parent | bd49325e3ba9fba3bbea2d32b3e7a71ec1934c55 (diff) | |
download | rails-291a098c111ff419506094e14c0186389b0020ca.tar.gz rails-291a098c111ff419506094e14c0186389b0020ca.tar.bz2 rails-291a098c111ff419506094e14c0186389b0020ca.zip |
Directly support stateful executor hooks
Also, make sure to call the +complete+ hooks if +run+ fails.
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/execution_wrapper.rb | 45 | ||||
-rw-r--r-- | activesupport/lib/active_support/reloader.rb | 8 |
2 files changed, 49 insertions, 4 deletions
diff --git a/activesupport/lib/active_support/execution_wrapper.rb b/activesupport/lib/active_support/execution_wrapper.rb index 2bd1c01d35..00c5745a25 100644 --- a/activesupport/lib/active_support/execution_wrapper.rb +++ b/activesupport/lib/active_support/execution_wrapper.rb @@ -19,6 +19,32 @@ module ActiveSupport set_callback(:complete, *args, &block) end + # Register an object to be invoked during both the +run+ and + # +complete+ steps. + # + # +hook.complete+ will be passed the value returned from +hook.run+, + # and will only be invoked if +run+ has previously been called. + # (Mostly, this means it won't be invoked if an exception occurs in + # a preceding +to_run+ block; all ordinary +to_complete+ blocks are + # invoked in that situation.) + def self.register_hook(hook, outer: false) + if outer + run_args = [prepend: true] + complete_args = [:after] + else + run_args = complete_args = [] + end + + to_run(*run_args) do + hook_state[hook] = hook.run + end + to_complete(*complete_args) do + if hook_state.key?(hook) + hook.complete hook_state[hook] + end + end + end + # Run this execution. # # Returns an instance, whose +complete!+ method *must* be invoked @@ -29,7 +55,15 @@ module ActiveSupport if active? Null else - new.tap(&:run!) + new.tap do |instance| + success = nil + begin + instance.run! + success = true + ensure + instance.complete! unless success + end + end end end @@ -37,11 +71,11 @@ module ActiveSupport def self.wrap return yield if active? - state = run! + instance = run! begin yield ensure - state.complete! + instance.complete! end end @@ -74,5 +108,10 @@ module ActiveSupport ensure self.class.active.delete Thread.current end + + private + def hook_state + @_hook_state ||= {} + end end end diff --git a/activesupport/lib/active_support/reloader.rb b/activesupport/lib/active_support/reloader.rb index 5d1f0e1e66..5623bdd349 100644 --- a/activesupport/lib/active_support/reloader.rb +++ b/activesupport/lib/active_support/reloader.rb @@ -43,7 +43,13 @@ module ActiveSupport # Initiate a manual reload def self.reload! executor.wrap do - new.tap(&:run!).complete! + new.tap do |instance| + begin + instance.run! + ensure + instance.complete! + end + end end prepare! end |