In the client, special care is taken when connect/write/read calls are interrupted, so the client does not lose track of spawned remote machines, otherwise it could leave dead zombies when its process receives SIGTERM/SIGINT.
The client persist connections with keep alive, so we speed up request throughput
The client still use SO_LINGER option to minimize TIME_WAIT connections during fork
Both client and server uses TCP_NODELAY to minimize connection latency
The server uses asynchronous IO, so we can supporting connecting multiple clients in parallel and forking them.
The server only shut downs when all asynchronous operations are either completed or cancelled. Meaning SIGTERM will not make it close right-away, it will only gracefully terminate when all clients sessions are gracefully closed by the client.
In the server, special care is taken during the fork.
Server uses SO_REUSEADDR flag
I've opted to disable threads, EPOLL and EVENTFD, to force Boost ASIO use select() based implementation, so we have less chance of issues with fork().
Boost ASIO was used for networking
Boost Beast was used for parsing HTTP requests/responses
There is no need to link any library, only header-only libraries from Boost were used.
Nlohmann JSON library was bundled in third party
make dep and make downloads were removed
I did some stress tests on the changes, ran thousands of requests/forks per second, found no issue so far.
Implementation details:
select()
based implementation, so we have less chance of issues withfork()
.make dep
andmake downloads
were removedThis replaces:
This should close:
222
157