File tree 5 files changed +130
-0
lines changed
activesupport/lib/active_support/concurrency
5 files changed +130
-0
lines changed Original file line number Diff line number Diff line change 1
1
require 'abstract_controller'
2
2
require 'action_dispatch'
3
+ require 'action_controller/metal/live'
3
4
4
5
module ActionController
5
6
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