Skip to content

Add IO#timeout attribute and use it for blocking IO operations.#5653

Merged
ioquatix merged 6 commits intoruby:masterfrom
ioquatix:io-timeout
Oct 7, 2022
Merged

Add IO#timeout attribute and use it for blocking IO operations.#5653
ioquatix merged 6 commits intoruby:masterfrom
ioquatix:io-timeout

Conversation

@ioquatix
Copy link
Member

@ioquatix ioquatix commented Mar 14, 2022

@ioquatix ioquatix force-pushed the io-timeout branch 8 times, most recently from 7c695e8 to 8f5a57e Compare March 15, 2022 19:17
@ioquatix ioquatix removed the Core/IO label May 8, 2022
@ioquatix ioquatix force-pushed the io-timeout branch 2 times, most recently from 1145393 to 5509ca0 Compare May 28, 2022 11:45
@ioquatix ioquatix force-pushed the io-timeout branch 2 times, most recently from e1be1c4 to 28890f0 Compare July 20, 2022 11:47
@ioquatix ioquatix force-pushed the io-timeout branch 13 times, most recently from 1b6a908 to 4070940 Compare September 12, 2022 08:17
@ioquatix ioquatix force-pushed the io-timeout branch 9 times, most recently from 5212173 to 2361573 Compare September 14, 2022 00:32
@nobu
Copy link
Member

nobu commented Sep 14, 2022

Consider the backward compatibility of ruby/openssl.

@ioquatix ioquatix force-pushed the io-timeout branch 2 times, most recently from 2f8b0df to 2e57446 Compare September 22, 2022 01:19
@ioquatix ioquatix force-pushed the io-timeout branch 2 times, most recently from 6438434 to 32e1a4f Compare October 6, 2022 10:15
@ioquatix ioquatix merged commit e4f91bb into ruby:master Oct 7, 2022
@ioquatix ioquatix deleted the io-timeout branch October 7, 2022 08:48

/**
* Set the timeout associated with the specified io object. This timeout is
* used as a best effort timeout to prevent operations from blocking forever.
Copy link
Contributor

Choose a reason for hiding this comment

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

I recommend to denote examples like "socket read/write".

Copy link
Contributor

Choose a reason for hiding this comment

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

ah, it's not a description for the method.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, I don't fully understand your feedback, but I'm happy to improve the documentation.

@ioquatix
Copy link
Member Author

ioquatix commented Oct 7, 2022

I have a follow up PR to improve the usage for backwards compatible extensions: #6507

@ioquatix
Copy link
Member Author

ioquatix commented Oct 7, 2022

Update to openssl gem: ruby/openssl#547

end

ruby_version_is "3.0" do
ruby_version_is "3.0"..."3.1" do
Copy link
Member

Choose a reason for hiding this comment

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

Should have been ..."3.2", fixed in ruby/spec@c3677cf

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks!

specified timeout. [[Feature #18630]]

```ruby
STDIN.timeout = 1
Copy link

@paddor paddor Jul 15, 2024

Choose a reason for hiding this comment

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

Sorry for asking here, but I'm reluctant to post a bug on Ruby Redmine. Should this feature work on all IO, like File and IO.fd_for(some_readiness_fd)? Because for me it doesn't.

require 'io/wait'
require 'socket'
require 'async'

begin
  STDIN.timeout = 1
  STDIN.read
rescue IO::TimeoutError
  puts "IO#timeout= worked on STDIN"
end


begin
  r, w = UNIXSocket.pair
  r.timeout = 1
  r.read
rescue IO::TimeoutError
  puts "IO#timeout= worked on UNIXSocket"
else
  puts "IO#timeout= did NOT work on UNIXSocket"
end


begin
  file = File.open '/dev/null'
  file.timeout = 1
  file.read
rescue IO::TimeoutError
  puts "IO#timeout= worked on File"
else
  puts "IO#timeout= did NOT work on File"
end


Async do
  file.read
rescue IO::TimeoutError
  puts "IO#timeout= worked on File in Async block"
else
  puts "IO#timeout= did NOT work on File in Async block"
end

Gives me:

IO#timeout= worked on STDIN
IO#timeout= worked on UNIXSocket
IO#timeout= did NOT work on File
IO#timeout= did NOT work on File in Async block

EDIT: It works for IO.fd_for(some_readiness_fd) inside an Async block, but not outside one. For File it doesn't work at all. Is it not supposed to?

Copy link
Member Author

Choose a reason for hiding this comment

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

I suppose timeouts should be considered advisory and/or best effort. Like, a safety net.

However, not working for File is probably to be expected, but I wonder if we can improve it. For sure, when running within Async, on the URing backend, it should be possible to make it work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants