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

Stream is closed or unusable #392

Closed
pfitzseb opened this issue Mar 4, 2019 · 12 comments · Fixed by #727
Closed

Stream is closed or unusable #392

pfitzseb opened this issue Mar 4, 2019 · 12 comments · Fixed by #727

Comments

@pfitzseb
Copy link
Contributor

pfitzseb commented Mar 4, 2019

With Julia 1.1 and HTTP 0.8.0 I'm getting a super weird error once the route is hit:

julia> using HTTP, Sockets

julia> ROUTER = HTTP.Router()
HTTP.Handlers.Router{Symbol("##363")}(HTTP.Handlers.RequestHandlerFunction{getfield(HTTP.Handlers, Symbol("##1#2"))}(getfield(HTTP.Handlers, Symbol("##1#2"))()), Dict{HTTP.Handlers.Route,Any}(), ^[[BDict{String,Val}())

julia> function test(req::HTTP.Request, args...)
           @show req
           @show resp =  HTTP.Response(
               400,
               [
                   "Access-Control-Allow-Origin" => "*"
               ]
           )
           return resp
       end
test (generic function with 1 method)

julia> HTTP.@register(ROUTER, "POST", "/test", test)

julia> HTTP.serve(ROUTER, Sockets.localhost, 8181)
┌ Error: error handling request
│   exception =
│    IOError: stream is closed or unusable
│    Stacktrace:
│     [1] check_open at ./stream.jl:323 [inlined]
│     [2] uv_write_async(::TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:871
│     [3] uv_write(::TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:845
│     [4] unsafe_write(::TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:901
│     [5] unsafe_write at /home/pfitzseb/.julia/packages/HTTP/GN0Te/src/ConnectionPool.jl:132 [inlined]
│     [6] macro expansion at ./gcutils.jl:87 [inlined]
│     [7] write at ./strings/io.jl:165 [inlined]
│     [8] writestartline(::HTTP.ConnectionPool.Transaction{TCPSocket}, ::HTTP.Messages.Response) at /home/pfitzseb/.julia/packages/HTTP/GN0Te/src/Messages.jl:428
│     [9] writeheaders(::HTTP.ConnectionPool.Transaction{TCPSocket}, ::HTTP.Messages.Response) at /home/pfitzseb/.julia/packages/HTTP/GN0Te/src/Messages.jl:439
│     [10] startwrite(::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{TCPSocket}}) at /home/pfitzseb/.julia/packages/HTTP/GN0Te/src/Streams.jl:85
│     [11] handle(::HTTP.Handlers.RequestHandlerFunction{getfield(HTTP.Handlers, Symbol("##1#2"))}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{TCPSocket}}) at /home/pfitzseb/.julia/packages/HTTP/GN0Te/src/Handlers.jl:273
│     [12] handle(::HTTP.Handlers.Router{Symbol("##363")}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{TCPSocket}}) at /home/pfitzseb/.julia/packages/HTTP/GN0Te/src/Handlers.jl:460
│     [13] #4 at /home/pfitzseb/.julia/packages/HTTP/GN0Te/src/Handlers.jl:339 [inlined]
│     [14] macro expansion at /home/pfitzseb/.julia/packages/HTTP/GN0Te/src/Servers.jl:352 [inlined]
│     [15] (::getfield(HTTP.Servers, Symbol("##13#14")){getfield(HTTP.Handlers, Symbol("##4#5")){HTTP.Handlers.Router{Symbol("##363")}},HTTP.ConnectionPool.Transaction{TCPSocket},HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{TCPSocket}}})() at ./task.jl:259
└ @ HTTP.Servers ~/.julia/packages/HTTP/GN0Te/src/Servers.jl:356
@pfitzseb
Copy link
Contributor Author

pfitzseb commented Mar 5, 2019

Turns out this happened because the request had a timeout of 1s set, which was too short when using the server for the first time and compiling lots of methods.

I feel like this should be handled more gracefully though.

@quinnj
Copy link
Member

quinnj commented May 31, 2019

Hmmm.........tricky issue. We could probably provide a sort of HTTP.serverinit() method that would run through and force compilation of all the key methods to ensure that at runtime, everything's all ready to go. Would that work?

@tlienart
Copy link
Contributor

tlienart commented Jun 6, 2019

I'm occasionally getting this error on 0.8.3 using LiveServer. Here's the stacktrace of the most recent event. It feels like it's the kind of errors that should be handled by HTTP itself (?)

┌ Error: error handling request
│   exception =
│    IOError: stream is closed or unusable
│    Stacktrace:
│     [1] check_open at ./stream.jl:323 [inlined]
│     [2] uv_write_async(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64, ::Task) at ./stream.jl:901
│     [3] uv_write(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:877
│     [4] unsafe_write(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:931
│     [5] unsafe_write at /Users/tlienart/.julia/packages/HTTP/wY7Vc/src/ConnectionPool.jl:134 [inlined]
│     [6] macro expansion at ./gcutils.jl:87 [inlined]
│     [7] write at ./strings/io.jl:177 [inlined]
│     [8] writestartline(::HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}, ::HTTP.Messages.Response) at /Users/tlienart/.julia/packages/HTTP/wY7Vc/src/Messages.jl:426
│     [9] writeheaders(::HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}, ::HTTP.Messages.Response) at /Users/tlienart/.julia/packages/HTTP/wY7Vc/src/Messages.jl:437
│     [10] startwrite(::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /Users/tlienart/.julia/packages/HTTP/wY7Vc/src/Streams.jl:85
│     [11] handle(::HTTP.Handlers.RequestHandlerFunction{getfield(LiveServer, Symbol("##9#14")){LiveServer.SimpleWatcher}}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /Users/tlienart/.julia/packages/HTTP/wY7Vc/src/Handlers.jl:278
│     [12] (::getfield(LiveServer, Symbol("##11#16")){HTTP.Handlers.RequestHandlerFunction{getfield(LiveServer, Symbol("##9#14")){LiveServer.SimpleWatcher}}})(::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /Users/tlienart/.julia/dev/LiveServer.jl/src/server.jl:227
│     [13] macro expansion at /Users/tlienart/.julia/packages/HTTP/wY7Vc/src/Servers.jl:360 [inlined]
│     [14] (::getfield(HTTP.Servers, Symbol("##13#14")){getfield(LiveServer, Symbol("##11#16")){HTTP.Handlers.RequestHandlerFunction{getfield(LiveServer, Symbol("##9#14")){LiveServer.SimpleWatcher}}},HTTP.ConnectionPool.Transaction{Sockets.TCPSocket},HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}})() at ./task.jl:268
└ @ HTTP.Servers ~/.julia/packages/HTTP/wY7Vc/src/Servers.jl:364

PS: we use readtimeout=0 in the HTTP.listen so I don't think the issue is caused by the same thing than for OP.

In the mean time does it make sense to use something like

try
  HTTP.handle(...)
catch e:
  if isa(e, IOError)
    # sleep and then try again
  else
    throw(e)
  end
end

?

@pfitzseb
Copy link
Contributor Author

pfitzseb commented Jun 6, 2019

Yeah, with

I feel like this should be handled more gracefully though.

I meant that the error should be presented more nicely or something like that (maybe even explain why this might happen).

PS: we use readtimeout=0 in the HTTP.listen so I don't think the issue is caused by the same thing than for OP.

The problem I had was that the client that made the request (aka a browser) was timing out, not the server.

@evanfields
Copy link

I'm encountering this phenomenon pretty frequently when using the AWS* packages, i.e. I am not interacting directly with HTTP.jl. Nothing seems to break, but this info/warning shows up frequently. Does that suggest that the warnings are spurious, a problem in HTTP.jl, a problem in AWSCore.jl, or a problem on Amazon's end?

@tlienart
Copy link
Contributor

mosty likely it's with HTTP.jl which is used by AWSCore

@mattBrzezinski
Copy link
Member

When running test in the package it causes issues with the server.jl HTTP.listen testset, causing it to fail or hang seemingly sporadically.

@itsdfish
Copy link

itsdfish commented Nov 22, 2019

I was wondering whether any progress has been made toward resolving this problem? I encountered this problem while trying to communicate with a websocket server via Java. The details can be found here. After tweaking the setup, I was able to successfully communicate with the websocket server, but the stream closed or is useable warning continued to display. It seems like part of the problem is that the error catching logic is producing false alarms in some cases. This behavior is consistent with that reported by evanfields.

Update:
It turns out the problem was that Java shutdown after the messages were sent. Sorry for the noise.

@drrmmng
Copy link

drrmmng commented Mar 19, 2020

I'm also getting this error when refreshing a web app created with https://github.com/waralex/Dashboards.jl

Maybe it's related to websites that are slow to load on the client side?

@pfitzseb
Copy link
Contributor Author

If you e.g. refresh the site while HTTP is still trying to answer (and write to the stream), you'll get this error. It's usually fine to ignore.

@clarkevans
Copy link
Contributor

This is still a very annoying issue in HTTP v0.8.19 -- when starting my server, and navigating to the given webpage in Firefox 84, this is the error it prints. As noted in many other threads, browsers do this. It's not an actionable exception.

┌ Error: error handling request
│   exception =
│    IOError: stream is closed or unusable
│    Stacktrace:
│     [1] check_open at ./stream.jl:328 [inlined]
│     [2] uv_write_async(::TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:959
│     [3] uv_write(::TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:922
│     [4] unsafe_write(::TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:1005
│     [5] unsafe_write at /home/cce/.julia/packages/HTTP/IAI92/src/ConnectionPool.jl:171 [inlined]
│     [6] write at ./strings/io.jl:183 [inlined]
│     [7] write(::HTTP.ConnectionPool.Transaction{TCPSocket}, ::String, ::String) at ./io.jl:613
│     [8] unsafe_write(::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{TCPSocket}}, ::Ptr{UInt8}, ::UInt64) at /home/cce/.julia/packages/HTTP/IAI92/src/Streams.jl:100
│     [9] unsafe_write at ./io.jl:622 [inlined]
│     [10] write at ./io.jl:645 [inlined]
│     [11] handle(::HTTP.Handlers.RequestHandlerFunction{typeof(TodoMVC.homepage)}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{TCPSocket}}) at /home/cce/.julia/packages/HTTP/IAI92/src/Handlers.jl:279
│     [12] handle(::HTTP.Handlers.Router{Symbol("##253")}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{TCPSocket}}) at /home/cce/.julia/packages/HTTP/IAI92/src/Handlers.jl:466
│     [13] #4 at /home/cce/.julia/packages/HTTP/IAI92/src/Handlers.jl:345 [inlined]
│     [14] macro expansion at /home/cce/.julia/packages/HTTP/IAI92/src/Servers.jl:367 [inlined]
│     [15] (::HTTP.Servers.var"#13#14"{HTTP.Handlers.var"#4#5"{HTTP.Handlers.Router{Symbol("##253")}},HTTP.ConnectionPool.Transaction{TCPSocket},HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{TCPSocket}}})() at ./task.jl:356
└ @ HTTP.Servers ~/.julia/packages/HTTP/IAI92/src/Servers.jl:373
^C
signal (2): Interrupt
in expression starting at /home/cce/TodoMVC.jl/test/serve.jl:13
epoll_pwait at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
uv__io_poll at /workspace/srcdir/libuv/src/unix/linux-core.c:270
uv_run at /workspace/srcdir/libuv/src/unix/core.c:359
jl_task_get_next at /buildworker/worker/package_linux64/build/src/partr.c:473
poptask at ./task.jl:704
wait at ./task.jl:712 [inlined]
task_done_hook at ./task.jl:442
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2214 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2398
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1690 [inlined]
jl_finish_task at /buildworker/worker/package_linux64/build/src/task.c:196
start_task at /buildworker/worker/package_linux64/build/src/task.c:715
unknown function (ip: (nil))
unknown function (ip: (nil))
(@v1.5) pkg> status HTTP
Status `~/.julia/environments/v1.5/Project.toml`
  [cd3eb016] HTTP v0.8.19
julia> versioninfo()
Julia Version 1.5.3
Commit 788b2c77c1 (2020-11-09 13:37 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Celeron(R) CPU J3455 @ 1.50GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, goldmont)

@NLaws
Copy link

NLaws commented May 3, 2021

I also have a similar stack trace:

┌ Error: error handling request
│   exception =
│    IOError: stream is closed or unusable
│    Stacktrace:
│     [1] check_open at ./stream.jl:328 [inlined]
│     [2] uv_write_async(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:959
│     [3] uv_write(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:922
│     [4] unsafe_write(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:1005
│     [5] unsafe_write at /root/.julia/packages/HTTP/cxgat/src/ConnectionPool.jl:172 [inlined]
│     [6] write at ./strings/io.jl:183 [inlined]
│     [7] unsafe_write(::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}, ::Ptr{UInt8}, ::UInt64) at /root/.julia/packages/HTTP/cxgat/src/Streams.jl:100
│     [8] unsafe_write at ./io.jl:622 [inlined]
│     [9] write at ./io.jl:645 [inlined]
│     [10] handle(::HTTP.Handlers.RequestHandlerFunction{typeof(health)}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /root/.julia/packages/HTTP/cxgat/src/Handlers.jl:280
│     [11] handle(::HTTP.Handlers.Router{Symbol("##1483")}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /root/.julia/packages/HTTP/cxgat/src/Handlers.jl:467
│     [12] #4 at /root/.julia/packages/HTTP/cxgat/src/Handlers.jl:346 [inlined]
│     [13] macro expansion at /root/.julia/packages/HTTP/cxgat/src/Servers.jl:406 [inlined]
│     [14] (::HTTP.Servers.var"#13#14"{HTTP.Handlers.var"#4#5"{HTTP.Handlers.Router{Symbol("##1483")}},HTTP.ConnectionPool.Transaction{Sockets.TCPSocket},HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}})() at ./task.jl:356
└ @ HTTP.Servers ~/.julia/packages/HTTP/cxgat/src/Servers.jl:417

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

Successfully merging a pull request may close this issue.

9 participants