Radicale icon indicating copy to clipboard operation
Radicale copied to clipboard

WIP: grab sockets from systemd

Open steelman opened this issue 4 years ago • 1 comments

Hi, this is my first attempt to teach Radicale systemd socket activation. Comments are more than welcome.

Context

systemd can open and bind sockets (of various types and not only sockets), wait for an incoming connection and start a service when a connection appears. It is a bit like inetd but with its own protocol that allows passing multiple listening sockets. systemd can give a service a socket either before or after accept(2). This patch assumes Radicale shall receive a listening socket, call accept(2) and wait for any later incoming connections.

The patch

The protocol for grabbing open sockets is rather simple but I decided to use listen_fds() function from the systemd.daemon module anyway. The module, however, is not required for Radicale to work the old way, neither on Linux nor on any other systems. BTW launchd on macos has its own socket activation protocol and it should be possible to implement both protocols side-by-side.

When Radicale detects open sockets during startup it ignores server.hosts configuration option from the configuration file and uses the passed sockets.

I decided to implement this functionality as a separate class to give a better overview of changes required to implement it. What bugs me a bit is that I had to copy the contents of server_bind() from WSGIServer and HTTPServer to avoid binding a socket that has already been bound by systemd. Is there a better way?

Future work.

systemd doesn't mind if a service decides to exit and activates it upon next incoming connection. Radicale can exit after some time of inactivity to preserve resources on smaller systems.

steelman avatar Jan 24 '21 19:01 steelman

This was already implemented at some point but removed again to keep the integrated WSGI server minimalistic: https://github.com/Kozea/Radicale/commit/2275ba4f9323e87eeac61f8811a4cc2773061e70 There are multiple WSGI servers (e.g. Gunicron or uWSGI) that support socket activation.

Unrud avatar Mar 22 '21 23:03 Unrud