Should we breathe new life into `readavailable`?
The function readavailable is in an awkward position. The documentation says:
Read available buffered data from a stream. Actual I/O is performed only if no data has already been buffered. The result is a
Vector{UInt8}.
This makes it sound like it does the following:
- If data is available in the internal buffer of the IO, read that
- Else, do one blocking operation to fill the internal buffer and then return whatever you get
This reply implies that that's indeed what it does.
It's also what the default definition of write(::IO, ::IO) implies it does
However, in the docstring, the sentence is followed by the warning:
│ Warning │ │ The amount of data returned is implementation-dependent; for example it can depend on the │ internal choice of buffer size. Other functions such as read should generally be used │ instead.
And the comments in https://github.com/JuliaLang/julia/issues/16821 also implies that this function should not be used at all.
But why? Isn't it quite useful to have a function that reads all the available data? To be sure, I'm a bit bummed out that readavailable doesn't actually read the available bytes, which you would really, really think it did from its name, but apparently also does a blocking operation if that number is zero.
I think it would be nice to either:
- Clarify that
readavailablewill return all of the bytes given bybytesavailableif that is nonzero, or else do one blocking read, and will read what becomes available from that, and remove the warning from the docstring, or - Slightly change the meaning of
readavailableto do what it says on the tin and read exactly the available bytes, no less, no more.
The latter would be nicer, but is slightly breaking and may be too breaking. And maybe there's a reason for the warning?
I was quite confused that readavailable is blocking when no bytes are available, and it caused a nasty bug. Let's start by documenting this blocking behaviour?
Also, the result of bytesavailable does not match the length of readavailable output in this example (Julia 1.12.2):
julia> begin
cmd = `julia -e "error(123)"`;
_stdout = Pipe();
_stderr = Pipe();
proc = run(
pipeline(Cmd(
cmd;
detach=true,
windows_hide=true,
), stdout=_stdout, stderr=_stderr),
wait=false,
)
sleep(2)
@info "result" bytesavailable(_stderr) readavailable(_stderr)
end
┌ Info: result
│ bytesavailable(_stderr) = 0
│ readavailable(_stderr) =
│ 260-element Vector{UInt8}:
│ 0x45
│ 0x52
│ 0x52
│ 0x4f
│ ⋮
│ 0x35
│ 0x30
└ 0x0a