diff options
author | José Valim <jose.valim@gmail.com> | 2011-04-16 10:28:47 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2011-04-16 10:28:47 +0200 |
commit | e30ca001efa861cc13259ca8287837174b24e679 (patch) | |
tree | ab47ef08d8c2e8773bb7fc6d6d24cda6cd32bf66 /actionpack/lib/action_view/flows.rb | |
parent | 2dd43c3f804176d114cdbfeb8a0f92a43155baee (diff) | |
download | rails-e30ca001efa861cc13259ca8287837174b24e679.tar.gz rails-e30ca001efa861cc13259ca8287837174b24e679.tar.bz2 rails-e30ca001efa861cc13259ca8287837174b24e679.zip |
Yo dawg, I heard you like streaming. So I put a fiber, inside a block, inside a body, so you can stream.
Diffstat (limited to 'actionpack/lib/action_view/flows.rb')
-rw-r--r-- | actionpack/lib/action_view/flows.rb | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/actionpack/lib/action_view/flows.rb b/actionpack/lib/action_view/flows.rb new file mode 100644 index 0000000000..1ac62961d1 --- /dev/null +++ b/actionpack/lib/action_view/flows.rb @@ -0,0 +1,64 @@ +require 'active_support/core_ext/string/output_safety' + +module ActionView + class OutputFlow + attr_reader :content + + def initialize + @content = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } + end + + def get(key) + @content[key] + end + + def set(key, value) + @content[key] = value + end + + def append(key, value) + @content[key] << value + end + end + + class StreamingFlow < OutputFlow + def initialize(flow, fiber) + @content = flow.content + @fiber = fiber + @root = Fiber.current.object_id + end + + # Try to get an stored content. If the content + # is not available and we are inside the layout + # fiber, we set that we are waiting for the given + # key and yield. + def get(key) + return super if @content.key?(key) + + if inside_fiber? + begin + @waiting_for = key + Fiber.yield + ensure + @waiting_for = nil + end + end + + super + end + + # Set the contents for the given key. This is called + # by provides and resumes back to the fiber if it is + # the key it is waiting for. + def set(key, value) + super + @fiber.resume if @waiting_for == key + end + + private + + def inside_fiber? + Fiber.current.object_id != @root + end + end +end
\ No newline at end of file |