You can tell I am a total newbie to server stuff, but it was a good learning experience working through all the code and traced the issue down to
where a call to
is made. accept takes an open socket (or creates one) and waits for a client to connect. When a client connects, it returns an active socket.
To shut down a running HttpServer, an obvious thing to try I think is
This does shutdown the server, but it does not die gracefully because accept from handle_http_request is still waiting for a client to connect.
Here is the code:
function accept(server::LibuvServer, client::LibuvStream) if server.status !=StatusActive throw(ArgumentError("server not connected, make sure \"listen\" has been called")) end while isopen(server) err = accept_nonblock(server,client) if err ==0 return client elseif err != UV_EAGAIN uv_error("accept",err) end stream_wait(server,server.connectnotify) end uv_error("accept", UV_ECONNABORTED) end
I traced the history of stream.jl (there must be an easier way than what I did - binary search clicking through "Blame" :)) to this commit:
error("accept: Server was closed while attempting to accept a client.")
Since then, I've written a new method:
and added it to my fork of HttpServer.jl and am considering submitting a PR. It basically allows the loop to exit gracefully, returns an inactive socket and deals with the fallout in handle_http_request from receiving a dud socket.
HOWEVER, I think an easier way to allow us to gracefully shutdown an HttpServer is to simply remove that error message.
Why should it be an error if a server is closed while attempting to accept a client?
If there is a good reason, then I can submit my PR to HttpServer.jl, but just wondering if removing that uv_error message would be acceptable.