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

Always read unbuffered when IO::Buffered#sync = true #5849

Merged
merged 3 commits into from May 22, 2018

Conversation

RX14
Copy link
Contributor

@RX14 RX14 commented Mar 21, 2018

Previously the sync option only affected writes, which wasn't optimal.

return nil unless sync?

byte = uninitialized UInt8
if read(Slice.new(pointerof(byte), 1)) == 1
Copy link
Contributor

@Sija Sija Mar 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

byte if read(Slice.new(pointerof(byte), 1)) == 1? Than you could skip else branch altogether.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer my more explicit version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. An else nil branch is always useless. Please drop it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the return nil above. return always returns nil. Skip the noise.

Copy link
Contributor Author

@RX14 RX14 Mar 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we agreed to skip the pointless bikeshedding about style. This kind of shit just drives away contributors. Until someone puts in the effort for an official style guide, the formatter is the style guide. And this formats.

Copy link
Contributor Author

@RX14 RX14 Mar 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also note that I copied this directly from io.cr:

crystal/src/io.cr

Lines 302 to 309 in 2d93603

def read_byte : UInt8?
byte = uninitialized UInt8
if read(Slice.new(pointerof(byte), 1)) == 1
byte
else
nil
end
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatter ain't a rewritter.

I never accepted the introduction of useless nils, and will always ask for them to be removed. Copying noise isn't a reason to keep it.

@ysbaddaden
Copy link
Contributor

ysbaddaden commented Mar 22, 2018

What if you trigger sync=true but the buffer ain't empty? I missed the spec.

io.read(16) # => buffers at most 8192 bytes
io.sync = true
io.read_byte # => what's read? buffer or IO?


byte = Bytes.new(1)
io.read_fully(byte)
byte[0].should eq('b'.ord.to_u8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe check that once the buffer is exhausted it will properly resume reading from the IO?

There are 2 independent tests (empty buffer, previously buffered), but the switch isn't tested.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add some more bytes to the IO::Memory after the first buffered read?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah thats a good idea.

io.sync = true
io.sync?.should be_true

io.read_byte.should eq('b'.ord.to_u8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Maybe even check for nil (EOF)?

@asterite
Copy link
Member

@RX14 How it wasn't optimal?

As far as I know, in Ruby IO#sync just affects writes.

@RX14
Copy link
Contributor Author

RX14 commented Apr 28, 2018

See #5843.

Read buffering sometimes isn't free or invisible - especially when working with systems-level programming - and there should absolutely be a way to turn it off.

@straight-shoota
Copy link
Member

Should it also be individually configurable for each direction? sync_read & sync_write?

@RX14 RX14 force-pushed the feature/io-buffered-sync-read branch 2 times, most recently from 369fcfb to a980e0b Compare May 4, 2018 17:21
@RX14 RX14 force-pushed the feature/io-buffered-sync-read branch from a980e0b to 2817969 Compare May 4, 2018 17:26
@RX14
Copy link
Contributor Author

RX14 commented May 4, 2018

I've rebased this and improved the specs. @ysbaddaden is this fine now?

If we add sync_read and sync_write it can be another PR.

@ysbaddaden
Copy link
Contributor

I'm fine with this, but @asterite said #sync only affects writes in Ruby, and maybe we should introduce #buffered instead to enable/disable the buffering and keep #sync as it is (sync writes)?

@RX14
Copy link
Contributor Author

RX14 commented May 5, 2018

If we did that, i'd rather just have a sync_read and sync_write property to be extra clear.

@RX14
Copy link
Contributor Author

RX14 commented May 5, 2018

This does fix a security bug though, so it'd be great to arrive on a decision pretty quick (before the next release).

@sdogruyol
Copy link
Member

Let's get this shipped first 👍

@bararchy
Copy link
Contributor

So.... LGTM? having security holes is not that good.

@RX14 RX14 merged commit 4e0dc9e into crystal-lang:master May 22, 2018
@RX14 RX14 added this to the Next milestone May 22, 2018
chris-huxtable pushed a commit to chris-huxtable/crystal that referenced this pull request Jun 6, 2018
* Always read unbuffered when IO::Buffered#sync = true

Previously the sync option only affected writes, which wasn't optimal.

* fixup! Always read unbuffered when IO::Buffered#sync = true

* fixup! Always read unbuffered when IO::Buffered#sync = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants