Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment: replacing FIFOBuffer with BufferStream/IOBuffer #110

Closed
samoconnor opened this issue Nov 6, 2017 · 1 comment
Closed

Experiment: replacing FIFOBuffer with BufferStream/IOBuffer #110

samoconnor opened this issue Nov 6, 2017 · 1 comment

Comments

@samoconnor
Copy link
Contributor

Following on from previous discussion of FIFOBuffer vs BufferStream #74 (comment):

I'd [be] glad review a PR that replaces it wholesale w/ BufferStream ...

@quinnj, as you know, I have a preference for using standard Base buffer types with HTTP rather than introducing the special purpose FIFOBuffer type.

Irrespective wether a decision is eventually made to replace FIFOBuffer with BufferStream or similar, I figure that it is a worthwhile exercise to try a quick hack that makes FIFOBuffer a very thin wrapper for IOBuffer/BufferStream, and see what we learn. e.g. we might find bugs, or behaviour inconsistencies in FIFOBuffer, or in BufferStream or IOBuffer etc.

A replacement FIFOBuffer that simply wraps IOBuffer/BufferStream is here.

Tweaks to the rest of HTTP.jl are on this branch: samoconnor@d572554

Results so far...

All the HTTP.jl tests are passing. The tests for my AWS packages also pass using this version of HTTP.jl.

I've found one new bug in Base: JuliaLang/julia#24465

I'm reminded of other inconsistencies in Base:

I noticed that the original read(::FIFOBuffer) was non-blocking. In my branch it is blocking (because it just wraps the Base function, so I've changed some uses of read() to readavailable() where non-blocking behaviour is needed (but, see this: JuliaLang/julia#16821).

The old FIFOBuffer eof() function never blocked. The wrapped Base.eof() does block as per the spec: "If the stream is not yet exhausted, this function will block to wait for more data if necessary, and then return false.". So, there are places were I replaced an eof() call with a nb_available() check or a comparison of bytes received with Content-Length.

The branch removes the fixed size buffer option from FIFOBuffer (because the wrapped BufferStream hides the buffer size and manages it internally). This means that the test/fifobuffer.jl test cases that probe the filling up of the fixed buffer are essentially now just hacked to pass. I don't think I properly understand the use case you had in mind for the fixed size feature. In all my usage it seems more convenient to let the buffer auto-size itself as needed. However, the underlying IOBuffer used by Base's BufferStream supports having a fixed size, so it should be easy enough to make a PR that adds a fixed size option to BufferStream if that is needed.

The String(::FIFOBuffer) function is useful. Base doesn't have a way to non-destructively read from (peek at?) an IO buffer, other than using mark/reset. I'm not sure if it would be better to call this peak(::FIFOBuffer, String). The name of the function would have to make sense for all the other IO types (including local files, TCP, TTY, etc).

Given that this experimental FIFOBuffer wrapping BufferStream/IOBuffer seems to work, it shouldn't be too hard to go the next step and replace FIFOBuffer with Base types.

@quinnj
Copy link
Member

quinnj commented Nov 26, 2017

As you can probably tell, I'm not in any rush to throw FIFOBuffer out. As most of Base IO stuff will probably not be completely set in stone, even maybe for 1.0, I foresee FIFOBuffer staying as is for at least the foreseeable future, if anything as a decoupled-from-Base experiment in how Base IO interfaces could improve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants