1

I am writing a simple web server with C++ that handles long-lived connections. However, I need to reload my web server from time to time. I wonder if there is a way that I can hand over the established connections from one process to another process to be able to retain my established connections after reload.

Would that be enough to only pass file descriptors? what would happen to connection states? Any similar open source project that does the same thing?

Any thoughts or ideas?

Thanks,

Amir
  • 5,996
  • 13
  • 48
  • 61
  • 1
    All you should have to do is pass the file descriptors, however, doing that outside of the parent-to-child process relationship is far more difficult. Are you planning on having the old web server start the new one? – Dave S Aug 21 '13 at 19:13
  • Yes, possibly. I prefer to not having parent-child process for now. – Amir Aug 22 '13 at 01:57

1 Answers1

2

I really have no idea whether this is possible, but I think not. If you fork() then the child will "inherit" the descriptors, but I don't know whether they behave like the should (though I suspect that they do.) And with forking, you can't run new code (can you?) Simple descriptor numbers are process-specific, so just passing them to a new, unrelated process won't work either, and they will be closed when your process terminates anyway.

One solution (in the absence of a simpler one,) is to break your server into two processes:

  1. Front-end: A very simple process that just accepts the connections, keep them open and forwards any data it receives to the second process, and vice versa.
  2. Server: The real web server, that does all the logic and processing, but does not communicate with the clients directly.

The first and second processes communicate via a simple protocol. One feature of this protocol must that it does support the second process being terminated and relaunched.

Now, you can reload the actual server process without losing the client connections (since they are handled by the front-end process.) And since this front-end is extremely simple and probably has very few configurations and bugs, you rarely need to reload it at all. (I'm assuming that you need to reload your server process because it runs into bugs that need to be fixed or you need to change configurations and stuff.)

Another important and helpful feature that this system can have is to be able to transition between server processes "gradually". That is, you already have a front-end and a server running, but you decide to reload the server. You launch another server process that connects to the front-end (while the old server is still running and connected,) and the front-end process forwards all the new client connections to the new server process (or even all the new requests coming from the existing client connections.) And when the old server finishes processing all the requests that it has under processing, it gracefully and cleanly exits.

As I said, this is a solution you might to try only if nothing easier and simpler is found.

yzt
  • 8,873
  • 1
  • 35
  • 44
  • 1
    FYI: Connecting a TCP socket and forking (and execing) a new child is exactly what the `inetd` daemon does, so it's possible, if the parent holds the socket and the child inherits it. – Dave S Aug 21 '13 at 19:20
  • Right you are! Thank you for pointing that out. So, connected socket descriptors *do* survive a `fork`+`exec`. So, all OP needs to do is to execute the next server process (to create a parent/child relationship) and somehow tell it what the interesting descriptors are. – yzt Aug 21 '13 at 19:25
  • @DaveS: Could you write an answer, describing this a bit more? I'm sure that would be a more suitable technique than my workaround. – yzt Aug 21 '13 at 19:30
  • Thanks for the response. I would like to point out though that my web server has proxy connections (in which my web server is actually the client). Those connection should be handed over as well. – Amir Aug 22 '13 at 02:16
  • 1
    I searched a little bit more and I saw send_fd and recv_fd. There is also a wrapper library for that. http://www.normalesup.org/~george/comp/libancillary/ any thoughts? – Amir Aug 22 '13 at 02:20