-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
streaming.rb
61 lines (50 loc) · 1.19 KB
/
streaming.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# frozen_string_literal: true
# Released under the MIT License.
# Copyright, 2022, by Samuel Williams.
require 'protocol/http/body/readable'
require 'protocol/http/body/stream'
module Protocol
module Rack
module Body
# Wraps a streaming response body into a compatible Protocol::HTTP body.
class Streaming < ::Protocol::HTTP::Body::Readable
def initialize(block, input = nil)
@block = block
@input = input
@output = nil
end
attr :block
class Output
def initialize(input, block)
stream = ::Protocol::HTTP::Body::Stream.new(input, self)
@fiber = Fiber.new do
block.call(stream)
@fiber = nil
end
end
def write(chunk)
Fiber.yield(chunk)
end
def close
@fiber = nil
end
def read
@fiber&.resume
end
end
# Invokes the block in a fiber which yields chunks when they are available.
def read
@output ||= Output.new(@input, @block)
return @output.read
end
def stream?
true
end
def call(stream)
raise "Streaming body has already been read!" if @output
@block.call(stream)
end
end
end
end
end