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

Http2Server.prototype.close Does Not Work as Expected #28214

Closed
anliting opened this issue Jun 13, 2019 · 5 comments · Fixed by #28581
Closed

Http2Server.prototype.close Does Not Work as Expected #28214

anliting opened this issue Jun 13, 2019 · 5 comments · Fixed by #28581
Labels
http2 Issues or PRs related to the http2 subsystem.

Comments

@anliting
Copy link

anliting commented Jun 13, 2019

node-v12.4.0-linux-x64/bin/node a.js

let
    http2=require('http2'),
    server=http2.createServer()
server.listen(8000,'127.0.0.1',()=>{
    let client=http2.connect('http://127.0.0.1:8000',()=>{
        console.log('listener called')
        server.close(()=>{
            console.log('close')
        })
    })
})

Expected: server.close stops the server from accepting new connections.
Result: console.log('close') never get called.

I aware that HTTP/2 works different to HTTP/1.1. And I can and should call session.close() on every active session to stop them from accepting new requests.

server.close seems also wait until there is no active sessions to call the callback function, which is not mentioned in the documentation.

And, to make there is no active sessions, I must first of all stop the server from accepting new connections.

@lpinca
Copy link
Member

lpinca commented Jun 30, 2019

server.close seems also wait until there is no active sessions to call the callback function, which is not mentioned in the documentation

I guess it wasn't documented because the behavior is the same of net.Server.prototype.close(). The callback is not called until there is an open connection.

@lpinca lpinca added the http2 Issues or PRs related to the http2 subsystem. label Jun 30, 2019
@cjihrig
Copy link
Contributor

cjihrig commented Jul 1, 2019

I think this is behaving as documented.

@anliting
Copy link
Author

anliting commented Jul 3, 2019

Oh, I see, it is documented. The callback is called when the server is closed, and the server waits, until there is no active connection, to close.

But I think the point is not whether it is documented or not:

An asynchronous operation usually call its callback function right after the operation is done.

As net.Server.prototype.close is documented, the operation is defined as "Stops the server from accepting new connections and keeps existing connections.". But the callback also waits until the server is closed to be called, rather than right after the operation is done.

Of course, it is not common does not mean it is bad. But think of the following situation:

Now I want to force a server to be closed with the following algorithm:

  1. stops the server from accepting new connections
  2. close all active connections

The second step must be executed after the first step. As the first step is an asynchronous operation, I would wait for its callback function to be called, to ensure that it is done. But the callback is called also implies that the second step is done. It is a dead lock.

Another approach:

  1. close all active connections
  2. stops the server from accepting new connections

It will not work, because once the server is still accepting new connections, there is no way to close all active connections in finite amount of steps.

@lpinca
Copy link
Member

lpinca commented Jul 6, 2019

  1. Stop the server from accepting new connections.
  2. Close all active connections.
  3. Wait for the callback.

There is no need to wait for the callback before closing connections. No new connection is established after server.close() is called.

@anliting
Copy link
Author

anliting commented Jul 7, 2019

No new connection is established after server.close() is called. @lpinca

net.Server.prototype.close:

Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event.

If the function is defined to "stop the server from accepting new connections and keep existing connections", and the work is done before it returns, I would rather say that it is synchronous instead of asynchronous; saying that it is asynchronous means that, only through waiting that callback, I can ensure the work is done.

However, the function is named close, and it, in a sense, closes the server; its current behavior still makes a sense (stop ..., and wait until all connections are ended). It can be explained in the documentation, that: The closing of a server, involves

  • stoping it from accepting new connection (synchronous), and
  • waiting until all connections are ended (asynchronous); and this function does the both.

cjihrig added a commit to cjihrig/node that referenced this issue Jul 8, 2019
This commit is an attempt to clarify the behavior of HTTP2's
server.close() method. Specifically, this makes it more clear
that the server stops allowing new sessions although the
callback may not be invoked for some time due to previously
existing sessions.

PR-URL: nodejs#28581
Fixes: nodejs#28214
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Jiawen Geng <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
targos pushed a commit that referenced this issue Jul 20, 2019
This commit is an attempt to clarify the behavior of HTTP2's
server.close() method. Specifically, this makes it more clear
that the server stops allowing new sessions although the
callback may not be invoked for some time due to previously
existing sessions.

PR-URL: #28581
Fixes: #28214
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Jiawen Geng <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http2 Issues or PRs related to the http2 subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants