diff options
author | Matthew Draper <matthew@trebex.net> | 2016-03-02 02:56:53 +1030 |
---|---|---|
committer | Matthew Draper <matthew@trebex.net> | 2016-03-02 02:56:53 +1030 |
commit | 541e4abb4b3710a384aefac83cafd0ab878c60bf (patch) | |
tree | 55603da9b6f9407a24c68e1d1fd53e109c4131e7 /activesupport/lib/active_support/execution_wrapper.rb | |
parent | ecdc0fbc872ea734adf29b3f9f3463b916235286 (diff) | |
parent | 60b53e9883bfd9f4edb640dbe2de89227b875e09 (diff) | |
download | rails-541e4abb4b3710a384aefac83cafd0ab878c60bf.tar.gz rails-541e4abb4b3710a384aefac83cafd0ab878c60bf.tar.bz2 rails-541e4abb4b3710a384aefac83cafd0ab878c60bf.zip |
Merge pull request #23807 from matthewd/executor
Publish AS::Executor and AS::Reloader APIs
Diffstat (limited to 'activesupport/lib/active_support/execution_wrapper.rb')
-rw-r--r-- | activesupport/lib/active_support/execution_wrapper.rb | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/execution_wrapper.rb b/activesupport/lib/active_support/execution_wrapper.rb new file mode 100644 index 0000000000..e784556abf --- /dev/null +++ b/activesupport/lib/active_support/execution_wrapper.rb @@ -0,0 +1,69 @@ +require 'active_support/callbacks' + +module ActiveSupport + class ExecutionWrapper + include ActiveSupport::Callbacks + + define_callbacks :run + define_callbacks :complete + + def self.to_run(*args, &block) + set_callback(:run, *args, &block) + end + + def self.to_complete(*args, &block) + set_callback(:complete, *args, &block) + end + + # Run this execution. + # + # Returns an instance, whose +complete!+ method *must* be invoked + # after the work has been performed. + # + # Where possible, prefer +wrap+. + def self.run! + new.tap(&:run!) + end + + # Perform the work in the supplied block as an execution. + def self.wrap + return yield if active? + + state = run! + begin + yield + ensure + state.complete! + end + end + + class << self # :nodoc: + attr_accessor :active + end + + def self.inherited(other) # :nodoc: + super + other.active = Concurrent::Hash.new(0) + end + + self.active = Concurrent::Hash.new(0) + + def self.active? # :nodoc: + @active[Thread.current] > 0 + end + + def run! # :nodoc: + self.class.active[Thread.current] += 1 + run_callbacks(:run) + end + + # Complete this in-flight execution. This method *must* be called + # exactly once on the result of any call to +run!+. + # + # Where possible, prefer +wrap+. + def complete! + run_callbacks(:complete) + self.class.active.delete Thread.current if (self.class.active[Thread.current] -= 1) == 0 + end + end +end |