开发者

Change port without losing data

I'm building开发者_开发技巧 a settings manager for my http server. I want to be able to change settings without having to kill the whole process. One of the settings I would like to be able to change is change the port number, and I've come up with a variety of solutions:

  • Kill the process and restart it
  • Call server.close() and then do the first approach
  • Call server.close() and initialize a new server in the same process

The problem is, I'm not sure what the repercussions of each approach is. I know that the first will work, but I'd really like to accomplish these things:

  • Respond to existing requests without accepting new ones
  • Maintain data in memory on the new server
  • Lose as little uptime as possible

Is there any way to get everything I want? The API for server.close() gives me hope: server.close(): Stops the server from accepting new connections.

My server will only be accessible by clients I create and by a very limited number of clients connecting through a browser, so I will be able to notify them of a port change. I understand that changing ports is generally a bad idea, but I want to allow for the edge-case where it is convenient or possibly necessary.

P.S. I'm using connect if that changes anything.

P.P.S. Relatively unrelated, but what would change if I were to use UNIX server sockets or change the host name? This might be a more relevant use-case.

P.P.P.S. This code illustrates the problem of using server.close(). None of the previous servers are killed, but more are created with access to the same resources...

var http = require("http");

var server = false,
    curPort = 8888;

function OnRequest(req,res){
    res.end("You are on port " + curPort);
    CreateServer(curPort + 1);
}
function CreateServer(port){
    if(server){
        server.close();
        server = false;
    }
    curPort = port;
    server = http.createServer(OnRequest);
    server.listen(curPort);
}
CreateServer(curPort);

Resources:

http://nodejs.org/docs/v0.4.4/api/http.html#server.close


I tested the close() function. It seems to do absolute nothing. The server still accepts connections on his port. restarting the process was the only way for me.

I used the following code:

var http = require("http");

var server = false;
function OnRequest(req,res){    
    res.end("server now listens on port "+8889);
    CreateServer(8889);
}
function CreateServer(port){
    if(server){
        server.close();
        server = false;
    }
    server = http.createServer(OnRequest);
    server.listen(port);
}
CreateServer(8888);


I was about to file an issue on the node github page when I decided to test my code thoroughly to see if it really is a bug (I hate filing bug reports when it's user error). I realized that the problem only manifests itself in the browser, because apparently browsers do some weird kind of HTTP request keep alive thing where it can still access dead ports because there's still a connection with the server.

What I've learned is this:

  • Browser caches keep ports alive unless the process on the server is killed
  • Utilities that do not keep caches by default (curl, wget, etc) work as expected
  • HTTP requests in node also don't keep the same type of cache that browsers do

For example, I used this code to prove that node http clients don't have access to old ports:

Client-side code:

var http = require('http'),
    client,
    request;

function createClient (port) {
  client = http.createClient(port, 'localhost');

  request = client.request('GET', '/create');
  request.end();

  request.on('response', function (response) {
      response.on('end', function () {
          console.log("Request ended on port " + port);
          setTimeout(function () {
              createClient(port);
          }, 5000);
      });
  });
}

createClient(8888);

And server-side code:

var http = require("http");

var server,
    curPort = 8888;

function CreateServer(port){
    if(server){
        server.close();
        server = undefined;
    }

    curPort = port;

    server = http.createServer(function (req, res) {
        res.end("You are on port " + curPort);
        if (req.url === "/create") {
            CreateServer(curPort);
        }
    });
    server.listen(curPort);
    console.log("Server listening on port " + curPort);
}
CreateServer(curPort);

Thanks everyone for the responses.


What about using cluster?

http://learnboost.github.com/cluster/docs/reload.html

It looks interesting!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜