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

[Compatibility] Adding IO#timeout #3066

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

itarato
Copy link
Collaborator

@itarato itarato commented May 25, 2023

Source: #3039

Introduce IO#timeout= and IO#timeout which can cause
IO::TimeoutError to be raised if a blocking operation exceeds the
specified timeout. [Feature #18630]

STDIN.timeout = 1
STDIN.read # => Blocking operation timed out! (IO::TimeoutError)

Caveat

This PR does not contain updating the error type for TCPSocket #open and #new. It seems we don't have the whole timeout logic implemented for that yet. I rather have them implemented in a separate PR to keep it clean.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label May 25, 2023
@itarato itarato self-assigned this May 25, 2023
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch from af77b4a to f9612a2 Compare May 25, 2023 21:10
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch 5 times, most recently from 6d60df1 to e4165b9 Compare May 26, 2023 19:57
@itarato itarato requested a review from eregon May 29, 2023 12:36
Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

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

This looks fine. My main concern is we shouldn't make the no-timeout-set case slower, but that seems already fine here.

I wonder if it should only affect read/write though, or other operations as well?

Also could you untag the CRuby tests for this: test/ruby/test_io_timeout.rb?

spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
src/main/ruby/truffleruby/core/io.rb Outdated Show resolved Hide resolved
src/main/ruby/truffleruby/core/posix.rb Outdated Show resolved Hide resolved
src/main/ruby/truffleruby/core/posix.rb Outdated Show resolved Hide resolved
src/main/ruby/truffleruby/core/posix.rb Outdated Show resolved Hide resolved
spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch 2 times, most recently from 490dfbb to ab4a579 Compare June 3, 2023 16:06
@itarato itarato requested a review from eregon June 3, 2023 16:21
@itarato itarato changed the title [WIP] [Compatibility] Adding IO#timeout [Compatibility] Adding IO#timeout Jun 3, 2023
@itarato itarato marked this pull request as ready for review June 3, 2023 16:28
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch 2 times, most recently from 759945e to cb1fa10 Compare June 5, 2023 14:40
spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
end

def timeout=(new_timeout)
self.nonblock = !Primitive.nil?(new_timeout)
Copy link
Member

Choose a reason for hiding this comment

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

Does io.timeout = nil sets nonblock to false?
Could you add specs for the interaction of timeout and nonblock?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure thing

src/main/ruby/truffleruby/core/posix.rb Outdated Show resolved Hide resolved
src/main/ruby/truffleruby/core/posix.rb Outdated Show resolved Hide resolved
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch from cb1fa10 to 92c516a Compare June 6, 2023 16:05
@itarato itarato requested a review from eregon June 6, 2023 16:06
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch from 92c516a to eb27291 Compare June 7, 2023 00:48
spec/ruby/core/io/timeout_spec.rb Show resolved Hide resolved
spec/ruby/core/io/timeout_spec.rb Show resolved Hide resolved
src/main/ruby/truffleruby/core/io.rb Outdated Show resolved Hide resolved
spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch from eb27291 to 607745e Compare June 7, 2023 18:11
spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
spec/ruby/core/io/timeout_spec.rb Show resolved Hide resolved
raise(TypeError, 'time interval must not be negative') if seconds < 0

seconds
end
Copy link
Member

Choose a reason for hiding this comment

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

Nice, it's a proper place for this helper method 👍.


poll_result = Truffle::IOOperations.poll(io, Truffle::IOOperations::POLLOUT, current_timeout)
raise IO::TimeoutError if poll_result == 0
Errno.handle_errno(Errno.errno) if poll_result == -1
Copy link
Member

Choose a reason for hiding this comment

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

major: Looks like error handling isn't accurate. Wondering if it's easy to test these cases.

It seems Truffle::IOOperations.poll:

  • returns false when it times out
  • calls Errno.handle_errno(errno) and consequently raises SystemCallError exception if there is error other than EINTR
  • returns nonnegative Integer otherwise

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As chatted about this - I'm attempting to update

from returning false to 0. The reason is - Posix's poll does return 0 on timeout (not exactly like this, when timeout happens on an EINTR, but the idea is pretty much equal). As well there is a lot of code doing poll(_) > 0 - which would raise with a boolean result.

And regarding:

calls Errno.handle_errno(errno) and consequently raises SystemCallError exception if there is error other than EINTR

Raising inside poll is fine, as far as I can tell we want that anyways. I would keep the check for -1 in read/write too, just to be safe and pragmatic.

src/main/ruby/truffleruby/core/io.rb Show resolved Hide resolved
src/main/ruby/truffleruby/core/posix.rb Outdated Show resolved Hide resolved
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch from 607745e to 5d9494f Compare June 8, 2023 16:06
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch from 5d9494f to a273dbf Compare June 8, 2023 20:06
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch from a273dbf to 9b3fb03 Compare June 14, 2023 14:35
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch 2 times, most recently from af440ac to cda497d Compare July 16, 2023 11:19
@itarato itarato force-pushed the feature/PA-3039-IO-timeout branch 2 times, most recently from de2a514 to 81dd5c6 Compare August 11, 2023 00:06
Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

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

Looks great, thank you!
Only a few remaining polishing touches needed.

spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
spec/ruby/core/io/timeout_spec.rb Outdated Show resolved Hide resolved
src/main/ruby/truffleruby/core/io.rb Outdated Show resolved Hide resolved
src/main/ruby/truffleruby/core/posix.rb Show resolved Hide resolved
Make timeout to be integer milliseconds in the loop
Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

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

Thank you for all the work on this PR, it's a non-trivial piece of functionality to integrate, it looks great.

@andrykonchin andrykonchin self-assigned this Aug 17, 2023
@andrykonchin andrykonchin added the in-ci The PR is being tested in CI. Do not push new commits. label Aug 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in-ci The PR is being tested in CI. Do not push new commits. OCA Verified All contributors have signed the Oracle Contributor Agreement. shopify
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants