Skip to content

Commit

Permalink
Prefer to use Fiber#transfer for reading/writing streaming chunks. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix authored Sep 2, 2024
1 parent cb1ca44 commit 623f28f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
22 changes: 19 additions & 3 deletions lib/protocol/rack/body/streaming.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,38 @@ def initialize(block, input = nil)
class Output
def initialize(input, block)
stream = ::Protocol::HTTP::Body::Stream.new(input, self)
@fiber = Fiber.new do

@from = nil

@fiber = Fiber.new do |from|
@from = from
block.call(stream)
@fiber = nil
end
end

def write(chunk)
Fiber.yield(chunk)
if from = @from
@from = nil
@from = from.transfer(chunk)
else
raise RuntimeError, "Stream is not being read!"
end
end

def close
@fiber = nil

if from = @from
@from = nil
from.transfer(nil)
end
end

def read
@fiber&.resume
raise RuntimeError, "Stream is already being read!" if @from

@fiber&.transfer(Fiber.current)
end
end

Expand Down
14 changes: 14 additions & 0 deletions test/protocol/rack/body/streaming.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,18 @@
expect(stream.string).to be == "HelloWorld"
end
end

with "nested fiber" do
let(:block) do
proc do |stream|
Fiber.new do
stream.write("Hello")
end.resume
end
end

it "can read a chunk" do
expect(body.read).to be == "Hello"
end
end
end

0 comments on commit 623f28f

Please sign in to comment.