## README This is an example of a socket-activated per-connection service (which is usually referred to as inetd-like service). A thorough explanation can be found at http://0pointer.de/blog/projects/inetd.html. ### Define a socket unit The key point here is to specify `Accept=yes`, which will make the socket accept connections (behaving like inetd) and pass only the resulting connection socket to the service handler. Create `/etc/systemd/system/baz.socket`: ```ini [Unit] Description=Baz Socket [Socket] ListenStream=127.0.0.1:9999 Accept=yes [Install] WantedBy=sockets.target ``` ### Define a service template unit We now create a service template from which the actual service will be instantiated on-demand. The lifetime of this service is usually very short (thus it may not appear at `systemctl`). Create `/etc/systemd/system/baz@.service`: ```ini [Unit] Description=Baz Service Requires=baz.socket [Service] Type=simple ExecStart=/usr/bin/python /opt/baz-service/serve.py %i StandardInput=socket StandardError=journal TimeoutStopSec=5 #RuntimeMaxSec=10 [Install] WantedBy=multi-user.target ``` An example service handler would be (located at `/opt/baz-service/serve.py` as specified at the service unit file): ```python #!/usr/bin/python import sys import logging logging.basicConfig(level=logging.INFO) instance = sys.argv[1] # The connected socket is duplicated to stdin/stdout data = sys.stdin.readline().strip() logging.info('baz-service: at instance %s, got request: %s', instance, data) sys.stdout.write(data.upper() + '\r\n') ``` ### Test Start (or enable it to start at boot time) the socket (verify it via `systemctl status baz.socket`), and make a request to the service: echo Hello| nc localhost 9999 You 'll notice that the socket's status has changed (i.e. `Accepted: 1`). Also, any log message generated by the on-demand service should be present at the journal (e.g. `journalctl --all| grep -e baz`).