Subject: 28.1; emacs.socket (systemd-managed, but start-on-demand like ALTERNATE_EDITOR="")

From: "Trent W. Buck" <[email-masked]>
Date: Thu, 25 Aug 2022 13:52:33 +1000

Right now there are three obvious ways to start emacs:

  1. just run "emacs foo.txt"

  2. "export ALTERNATE_EDITOR=", then "emacsclient foo.txt"

  3. "systemctl enable --now emacs.service", then "emacsclient foo.txt"

The benefit of #2 is that emacs only starts on-demand, i.e.
if you turn on your computer and don't run Emacs for a week,
you don't pay the ~80MB memory cost of "emacs --daemon" for a week.

The drawback of #2 (compared to #3) is that emacs starts in an
unpredictable environment -- it inherits whatever state (working
directory, ~/.profile environment variables, &c) of the first process
that ran emacsclient.  For example, if it was run from "git commit" in
xterm it might have completely different DISPLAY state to if it was run
from gnome-shell's wayland launcher.

Whether these are REALLY benefits and drawbacks is highly debatable.
People with slow init.el probably hate on-demand launching.
People with nontrivial ~/.profile don't want to faff about with
systemd-specific environment.d(5).

However.

I'd like an option to have BOTH AT ONCE,
i.e. a predictable-environment on-demand emacs --daemon.

I think to do this, you need to do something like...

  1. create an emacs.socket like

       [Socket]
       ListenStream=$XDG_RUNTIME_DIR/emacs/server

  2. patch emacs --daemon like

       if fd 3 is already open,
          it must be because systemd opened the socket for us
          so just start using it
       otherwise,
          existing behaviour, open the socket ourselves

At that point, anyone using emacs.service directly can carry on as
before.  But if emacs.socket stats emacs.service indirectly, it'll all
Just Work.

Here are examples of #2 from some other daemons:

    https://github.com/pantheon-systems/nginx/blob/master/nginx-systemd-socket-activation.patch#L284-L291
    https://github.com/mirror/busybox/commit/9b3b9790b32d440eb89af5edda70a66b1829e861
    https://github.com/unbit/uwsgi/blob/d58a832c81c2c96ae0f6e72614e1cc47f4b5d332/core/setup_utils.c#L6-L25

systemd documentation:

    https://www.freedesktop.org/software/systemd/man/daemon.html#Socket-Based%20Activation
    https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html

PS: if you want to get REAL fancy, you could also have emacs
automatically M-x kill-emacs if there were no open emacsclient and no
open network processes (e.g. M-x irc) and no unsaved files.
For example, on Debian 10+ cups-daemon does this by default.
But that is probably a bit TOO clever :-)