IO :: EAGAINWaitReadable:资源暂时不可用 - 读取将阻止

tis*_*oro 6 ruby ruby-on-rails-4

当我尝试使用"socket"库中的方法"read_nonblock"时,出现以下错误

IO::EAGAINWaitReadable: Resource temporarily unavailable - read would block
Run Code Online (Sandbox Code Playgroud)

但是当我通过终端上的IRB尝试它时,它工作正常

如何让它读取缓冲区?

Мал*_*евъ 3

当我尝试使用“socket”库中的“read_nonblock”方法时,出现以下错误

当缓冲区中的数据未准备好时,这是预期的行为。由于该异常IO::EAGAINWaitReadable源自 ruby​​ 版本2.1.0,因此在旧版本中,您必须捕获IO::WaitReadable额外的端口选择并重试。按照ruby​​ 文档中的建议进行操作:

begin
   result = io.read_nonblock(maxlen)
rescue IO::WaitReadable
   IO.select([io])
   retry
end
Run Code Online (Sandbox Code Playgroud)

对于较新版本的 os ruby​​,您也应该捕获IO::EAGAINWaitReadable,但只是重试超时或无限读取。我还没有在文档中找到该示例,但请记住它没有端口选择:

begin
   result = io.read_nonblock(maxlen)
rescue IO::EAGAINWaitReadable
   retry
end
Run Code Online (Sandbox Code Playgroud)

然而,我的一些调查表明,最好在 上进行端口选择IO::EAGAINWaitReadable,这样您就可以获得:

begin
   result = io.read_nonblock(maxlen)
rescue IO::WaitReadable, IO::EAGAINWaitReadable
   IO.select([io])
   retry
end
Run Code Online (Sandbox Code Playgroud)

IO::EAGAINWaitReadable要支持具有两个版本的异常的代码,只需在子句下声明in lib/ core的定义if

if ! ::IO.const_defined?(:EAGAINWaitReadable)
   class ::IO::EAGAINWaitReadable; end
end
Run Code Online (Sandbox Code Playgroud)