class Writable
A dynamic body which you can write to and read from.
Nested
Definitions
def initialize(length = nil, queue: Thread::Queue.new)
Initialize the writable body.
Signature
-
parameter
length
Integer
The length of the response body if known.
-
parameter
queue
Thread::Queue
Specify a different queue implementation, e.g.
Thread::SizedQueue
to enable back-pressure.
Implementation
def initialize(length = nil, queue: Thread::Queue.new)
@length = length
@queue = queue
@count = 0
@error = nil
end
attr :length
Signature
-
attribute
Integer
The length of the response body if known.
def close(error = nil)
Stop generating output; cause the next call to write to fail with the given error. Does not prevent existing chunks from being read. In other words, this indicates both that no more data will be or should be written to the body.
Signature
-
parameter
error
Exception
The error that caused this body to be closed, if any. Will be raised on the next call to
Protocol::HTTP::Body::Writable#read
.
Implementation
def close(error = nil)
@error ||= error
@queue.clear
@queue.close
super
end
def closed?
Whether the body is closed. A closed body can not be written to or read from.
Signature
-
returns
Boolean
Whether the body is closed.
Implementation
def closed?
@queue.closed?
end
def ready?
Signature
-
returns
Boolean
Whether the body is ready to be read from, without blocking.
Implementation
def ready?
!@queue.empty? || @queue.closed?
end
def empty?
Indicates whether the body is empty. This can occur if the body has been closed, or if the producer has invoked Protocol::HTTP::Body::Writable#close_write
and the reader has consumed all available chunks.
Signature
-
returns
Boolean
Whether the body is empty.
Implementation
def empty?
@queue.empty? && @queue.closed?
end
def read
Read the next available chunk.
Signature
-
returns
String | Nil
The next chunk, or
nil
if the body is finished.-
raises
Exception
If the body was closed due to an error.
Implementation
def read
if @error
raise @error
end
# This operation may result in @error being set.
chunk = @queue.pop
if @error
raise @error
end
return chunk
end
def write(chunk)
Write a single chunk to the body. Signal completion by calling Protocol::HTTP::Body::Writable#close_write
.
Signature
-
parameter
chunk
String
The chunk to write.
-
raises
Closed
If the body has been closed without error.
-
raises
Exception
If the body has been closed due to an error.
Implementation
def write(chunk)
if @queue.closed?
raise(@error || Closed)
end
@queue.push(chunk)
@count += 1
end
def close_write(error = nil)
Signal that no more data will be written to the body.
Signature
-
parameter
error
Exception
The error that caused this body to be closed, if any.
Implementation
def close_write(error = nil)
@error ||= error
@queue.close
end
def output
Create an output wrapper which can be used to write chunks to the body.
If a block is given, and the block raises an error, the error will used to close the body by invoking Protocol::HTTP::Body::Writable#close
with the error.
Signature
-
yields
{|output| ...}
if a block is given.
-
parameter
output
Output
The output wrapper.
-
parameter
-
returns
Output
The output wrapper.
Implementation
def output
output = Output.new(self)
unless block_given?
return output
end
begin
yield output
rescue => error
raise error
ensure
output.close(error)
end
end
def inspect
Inspect the body.
Signature
-
returns
String
A string representation of the body.
Implementation
def inspect
if @error
"\#<#{self.class} #{@count} chunks written, #{status}, error=#{@error}>"
else
"\#<#{self.class} #{@count} chunks written, #{status}>"
end
end
def status
Signature
-
returns
String
A string representation of the body's status.
Implementation
def status
if @queue.empty?
if @queue.closed?
"closed"
else
"waiting"
end
else
if @queue.closed?
"closing"
else
"ready"
end
end
end