3

I want a service to start on demand rather than on boot. To do that I could use systemd socket activation (with the service and socket files).

But this is a resource limited server, so after some time (e.g. 1 hour) of inactivity, I want to stop the service (until it is triggered again). How can I do that?

I looked through some of the documentation but I can't figure out if this is supported.


Update:
Assuming this is unsupported, the use case is still probably quite common. What would be a good way / workaround to achieve this?

  • I don’t think this is supported in systemd, but if your service exits (successfully) after it detects it’s been idle, systemd should be able to start it again when the next connection is made. – Lucas Werkmeister Sep 26 '18 at 12:27
1

Socket activation in systemd can work in two modes:

  • Accept=true: systemd keeps the listening socket, accepts every incoming connection, spawns a new process for each connection and passes the established socket to it. This case is trivial (each process exits when it's done).
  • Accept=false: systemd creates the listening socket and watches it for incoming connection. As soon as one comes in, systemd spawns the service and passes the listening socket to it. The service then accepts the incoming connection and any subsequent ones. Systemd doesn't track what's happening on the socket anymore, so it can't detect inactivity.

In the latter case, I think the only truly clean solution is to modify the application to make it exit when it's idle for some time. If you can't do that, a crude workaround could be to set up cron or a systemd timer to kill the service once an hour. This could be a reasonable approximation if the service is only spawned really infrequently.

Note that the use case is probably pretty rare. A process sitting in poll()/select() waiting for a connection doesn't consume any CPU time, so the only resource that's used in that situation is memory. It's probably both easier and more efficient to just set up some swap and let the kernel decide whether it's worth keeping the process in RAM all the time or not.

  • It isn't a rare use case - many people use "small" VPSs with limited memory, so having a few services sitting idle is wasteful. Nonetheless thanks for explaining it so thoroughly, I'll need to rethink this problem. I'll look into monitoring for idle outside of systemd. – lonix Sep 28 '18 at 4:43
1

If your service is capable of being socket activated, then you can use Accept=yes in the socket unit. Then a new instance of your service would be executed for every connection and stopped when the socket is closed.

  • 1
    This is an interesting idea. But that means that it would be stopped every time, which is resource intensive. Is there a away to stop after "idle" time instead? – lonix Sep 26 '18 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.