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

Bad file descriptor thrown while making request on Windows #163

Open
ZumiKua opened this issue Jun 21, 2024 · 3 comments
Open

Bad file descriptor thrown while making request on Windows #163

ZumiKua opened this issue Jun 21, 2024 · 3 comments

Comments

@ZumiKua
Copy link

ZumiKua commented Jun 21, 2024

  0.0s     warn: Async::Task [oid=0x244] [ec=0x258] [pid=13816] [2024-06-21 15:10:44 +0800]
               | Task may have ended with unhandled exception.
               |   Errno::EBADF: Bad file descriptor @ io_fillbuf - fd:5 C:/WINDOWS/System32/drivers/etc/hosts
               |   → C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 193:in `each'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 193:in `block (2 levels) in lazy_initialize'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 192:in `open'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 192:in `block in lazy_initialize'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 188:in `synchronize'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 188:in `lazy_initialize'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 236:in `each_address'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 116:in `block in each_address'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 115:in `each'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 115:in `each_address'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 102:in `getaddresses'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/resolv.rb 51:in `getaddresses'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-2.12.0/lib/async/scheduler.rb 195:in `address_resolve'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/socket.rb 227:in `getaddrinfo'
               |     C:/Ruby31-x64/lib/ruby/3.1.0/socket.rb 227:in `foreach'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/io-endpoint-0.10.3/lib/io/endpoint/host_endpoint.rb 40:in `connect'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/io-endpoint-0.10.3/lib/io/endpoint/ssl_endpoint.rb 155:in `connect'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-http-0.67.1/lib/async/http/endpoint.rb 189:in `connect'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-http-0.67.1/lib/async/http/client.rb 197:in `block in make_pool'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-pool-0.6.1/lib/async/pool/controller.rb 286:in `create_resource'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-pool-0.6.1/lib/async/pool/controller.rb 341:in `get_resource'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-pool-0.6.1/lib/async/pool/controller.rb 305:in `block in available_resource'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-2.12.0/lib/async/semaphore.rb 87:in `acquire'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-pool-0.6.1/lib/async/pool/controller.rb 304:in `available_resource'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-pool-0.6.1/lib/async/pool/controller.rb 268:in `wait_for_resource'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-pool-0.6.1/lib/async/pool/controller.rb 117:in `acquire'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-http-0.67.1/lib/async/http/client.rb 103:in `call'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/protocol-http-0.26.5/lib/protocol/http/middleware.rb 43:in `call'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/protocol-http-0.26.5/lib/protocol/http/accept_encoding.rb 35:in `call'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-http-0.67.1/lib/async/http/internet.rb 50:in `call'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-http-0.67.1/lib/async/http/internet.rb 63:in `block (2 levels) in <class:Internet>'
               |     ./a.rb:6 in `block in <main>'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-2.12.0/lib/async/task.rb 164:in `block in run'
               |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/async-2.12.0/lib/async/task.rb 377:in `block in schedule'

Ruby version is ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [x64-mingw-ucrt]
async http version is 0.67.1

It seems that this exception is thrown while calling Resolv.getaddresses, if I call this method manually, this exception goes away.

require 'async'
require 'async/http/internet'
p Resolv.getaddresses("example.com") # comment this line will make this code throw.
Async do
  internet = Async::HTTP::Internet.new
  response = internet.get("https://example.com")
  p response.read
ensure
  internet.close
end
@ioquatix
Copy link
Member

I see the issue but I'm not able to fix it at this time. I'm planning to support IOCP on Windows which should fix this. Are you able to use WSL2 instead?

@ZumiKua
Copy link
Author

ZumiKua commented Jun 21, 2024

Thanks for your reply!

The workaround of calling Resolv.getaddresses is sufficient for me (I'm writing a small one-time use script), so no WSL2 is needed I think.

Please take your time to fix this issue, thanks again for your wonderful work.

@ioquatix
Copy link
Member

The reason why it works is because file IO is not working correctly in the fiber scheduler. By doing Resolv.getaddresses("example.com") outside of the Async{} block, it's loading the hosts file from disk and caching it.

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