Skip to content

Async::HTTP causes error with io-stream 0.8.0 #8

@Watson1978

Description

@Watson1978

After updating io-stream to the latest version, Async::HTTP causes errors on Windows platform.
We met this problem with Ruby 3.3 and 3.4 on Windows.

Reproduce

require 'bundler/inline'
gemfile do
  source 'https://rubygems.org'
#  gem 'io-stream', '= 0.7.0'
  gem 'io-stream', '= 0.8.0'
  gem 'async'
  gem 'async-http'
end

require 'net/http'
require 'uri'

endpoint = Async::HTTP::Endpoint.parse('http://127.0.0.1:8080/hello')

Thread.new do
  Sync do |task|
    Async do
      server = Async::HTTP::Server.for(endpoint) do |request|
        ::Protocol::HTTP::Response[200, {}, ["Hello World"]]
      end

      server.run
    end
  end
end

sleep 1

url = URI.parse("http://127.0.0.1:8080/hello")
req = Net::HTTP::Get.new(url)
Net::HTTP.start(url.host, url.port) do |http|
  puts "-" * 80
  puts "[debug] Requesting #{url}"
  puts http.request(req).body
end

sleep 1
  • Result with io-stream v0.8.0
PS C:\src\sandbox\ruby> ruby net.rb
C:/Ruby34-x64/lib/ruby/3.4.0/win32/registry.rb:2: warning: fiddle/import is found in fiddle, which will no longer be part of the default gems starting from Ruby 3.5.0.
You can add fiddle to your Gemfile or gemspec to silence this warning.
--------------------------------------------------------------------------------
[debug] Requesting http://127.0.0.1:8080/hello
  0.0s     warn: Async::Task: Reading HTTP/1.1 requests for Async::HTTP::Protocol::HTTP1::Server. [oid=0x318] [ec=0x320] [pid=9604] [2025-06-24 17:03:08 +0900]
               | Task may have ended with unhandled exception.
               |   Errno::EBADF: Bad file descriptor
               |   → C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/buffered.rb 111:in 'IO#write'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/buffered.rb 111:in 'IO::Stream::Buffered#syswrite'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/writable.rb 85:in 'IO::Stream::Writable#drain'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/writable.rb 33:in 'block in IO::Stream::Writable#flush'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/writable.rb 32:in 'Thread::Mutex#synchronize'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/writable.rb 32:in 'IO::Stream::Writable#flush'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/protocol-http1-0.34.0/lib/protocol/http1/connection.rb 623:in 'Protocol::HTTP1::Connection#write_fixed_length_body'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/protocol-http1-0.34.0/lib/protocol/http1/connection.rb 751:in 'Protocol::HTTP1::Connection#write_body'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-http-0.89.0/lib/async/http/protocol/http1/server.rb 134:in 'block in Async::HTTP::Protocol::HTTP1::Server#each'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-2.25.0/lib/async/task.rb 331:in 'Async::Task#defer_stop'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-http-0.89.0/lib/async/http/protocol/http1/server.rb 81:in 'Async::HTTP::Protocol::HTTP1::Server#each'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-http-0.89.0/lib/async/http/server.rb 50:in 'Async::HTTP::Server#accept'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-endpoint-0.15.2/lib/io/endpoint/wrapper.rb 216:in 'block (2 levels) in IO::Endpoint::Wrapper#accept'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-2.25.0/lib/async/task.rb 201:in 'block in Async::Task#run'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-2.25.0/lib/async/task.rb 439:in 'block in Async::Task#schedule'
 0.03s     warn: Async::Task: Reading HTTP/1.1 requests for Async::HTTP::Protocol::HTTP1::Server. [oid=0x328] [ec=0x330] [pid=9604] [2025-06-24 17:03:08 +0900]
               | Task may have ended with unhandled exception.
               |   Errno::EBADF: Bad file descriptor
               |   → C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/buffered.rb 111:in 'IO#write'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/buffered.rb 111:in 'IO::Stream::Buffered#syswrite'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/writable.rb 85:in 'IO::Stream::Writable#drain'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/writable.rb 33:in 'block in IO::Stream::Writable#flush'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/writable.rb 32:in 'Thread::Mutex#synchronize'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-stream-0.8.0/lib/io/stream/writable.rb 32:in 'IO::Stream::Writable#flush'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/protocol-http1-0.34.0/lib/protocol/http1/connection.rb 623:in 'Protocol::HTTP1::Connection#write_fixed_length_body'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/protocol-http1-0.34.0/lib/protocol/http1/connection.rb 751:in 'Protocol::HTTP1::Connection#write_body'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-http-0.89.0/lib/async/http/protocol/http1/server.rb 134:in 'block in Async::HTTP::Protocol::HTTP1::Server#each'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-2.25.0/lib/async/task.rb 331:in 'Async::Task#defer_stop'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-http-0.89.0/lib/async/http/protocol/http1/server.rb 81:in 'Async::HTTP::Protocol::HTTP1::Server#each'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-http-0.89.0/lib/async/http/server.rb 50:in 'Async::HTTP::Server#accept'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/io-endpoint-0.15.2/lib/io/endpoint/wrapper.rb 216:in 'block (2 levels) in IO::Endpoint::Wrapper#accept'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-2.25.0/lib/async/task.rb 201:in 'block in Async::Task#run'
               |     C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/async-2.25.0/lib/async/task.rb 439:in 'block in Async::Task#schedule'
C:/Ruby34-x64/lib/ruby/3.4.0/net/protocol.rb:237:in 'Net::BufferedIO#rbuf_fill': end of file reached (EOFError)
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/protocol.rb:199:in 'Net::BufferedIO#readuntil'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/protocol.rb:209:in 'Net::BufferedIO#readline'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/http/response.rb:158:in 'Net::HTTPResponse.read_status_line'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/http/response.rb:147:in 'Net::HTTPResponse.read_new'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/http.rb:2414:in 'block in Net::HTTP#transport_request'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/http.rb:2405:in 'Kernel#catch'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/http.rb:2405:in 'Net::HTTP#transport_request'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/http.rb:2378:in 'Net::HTTP#request'
	from net.rb:32:in 'block in <main>'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/http.rb:1626:in 'Net::HTTP#start'
	from C:/Ruby34-x64/lib/ruby/3.4.0/net/http.rb:1064:in 'Net::HTTP.start'
	from net.rb:29:in '<main>'

it causes error with same net/http stacktrace.

  • Result with io-stream v0.7.0
PS C:\src\sandbox\ruby> ruby net.rb
C:/Ruby34-x64/lib/ruby/3.4.0/win32/registry.rb:2: warning: fiddle/import is found in fiddle, which will no longer be part of the default gems starting from Ruby 3.5.0.
You can add fiddle to your Gemfile or gemspec to silence this warning.
--------------------------------------------------------------------------------
[debug] Requesting http://127.0.0.1:8080/hello
Hello World

it works well

Related to fluent/fluentd#5009

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions