File tree Expand file tree Collapse file tree
activesupport/lib/active_support/concurrency Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11require 'abstract_controller'
22require 'action_dispatch'
3+ require 'action_controller/metal/live'
34
45module ActionController
56 extend ActiveSupport ::Autoload
Original file line number Diff line number Diff line change 1+ require 'action_dispatch/http/response'
2+
3+ module ActionController
4+ module Live
5+ class Response < ActionDispatch ::Response
6+ class Buffer < ActionDispatch ::Response ::Buffer # :nodoc:
7+ def initialize ( response )
8+ @response = response
9+ @buf = Queue . new
10+ end
11+
12+ def write ( string )
13+ unless @response . committed?
14+ @response . headers [ "Cache-Control" ] = "no-cache"
15+ @response . headers . delete ( "Content-Length" )
16+ end
17+
18+ super
19+ end
20+
21+ def each
22+ while str = @buf . pop
23+ yield str
24+ end
25+ end
26+
27+ def close
28+ super
29+ @buf . push nil
30+ end
31+ end
32+
33+ private
34+
35+ def build_buffer ( response , body )
36+ buf = Buffer . new response
37+ body . each { |part | buf . write part }
38+ buf
39+ end
40+ end
41+ end
42+ end
Original file line number Diff line number Diff line change 1+ require 'abstract_unit'
2+
3+ module ActionController
4+ class StreamingResponseTest < ActionController ::TestCase
5+ class TestController < ActionController ::Base
6+ def self . controller_path
7+ 'test'
8+ end
9+
10+ def basic_stream
11+ %w{ hello world } . each do |word |
12+ response . stream . write word
13+ response . stream . write "\n "
14+ end
15+ response . stream . close
16+ end
17+ end
18+
19+ tests TestController
20+
21+ def test_write_to_stream
22+ get :basic_stream
23+ assert_equal "hello\n world\n " , @response . body
24+ end
25+ end
26+ end
Original file line number Diff line number Diff line change 1+ require 'abstract_unit'
2+ require 'active_support/concurrency/latch'
3+
4+ module ActionController
5+ module Live
6+ class ResponseTest < ActiveSupport ::TestCase
7+ def setup
8+ @response = Live ::Response . new
9+ end
10+
11+ def test_parallel
12+ latch = ActiveSupport ::Concurrency ::Latch . new
13+
14+ t = Thread . new {
15+ @response . stream . write 'foo'
16+ latch . await
17+ @response . stream . close
18+ }
19+
20+ @response . each do |part |
21+ assert_equal 'foo' , part
22+ latch . release
23+ end
24+ assert t . join
25+ end
26+
27+ def test_setting_body_populates_buffer
28+ @response . body = 'omg'
29+ @response . close
30+ assert_equal [ 'omg' ] , @response . body_parts
31+ end
32+ end
33+ end
34+ end
Original file line number Diff line number Diff line change 1+ require 'thread'
2+ require 'monitor'
3+
4+ module ActiveSupport
5+ module Concurrency
6+ class Latch
7+ def initialize ( count = 1 )
8+ @count = count
9+ @lock = Monitor . new
10+ @cv = @lock . new_cond
11+ end
12+
13+ def release
14+ @lock . synchronize do
15+ @count -= 1 if @count > 0
16+ @cv . broadcast if @count . zero?
17+ end
18+ end
19+
20+ def await
21+ @lock . synchronize do
22+ @cv . wait_while { @count > 0 }
23+ end
24+ end
25+ end
26+ end
27+ end
You can’t perform that action at this time.
0 commit comments