unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Sockets in Shepherd, and Emacs, oh my!
@ 2022-04-08 18:40 Liliana Marie Prikler
  2022-04-10 20:40 ` Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Liliana Marie Prikler @ 2022-04-08 18:40 UTC (permalink / raw)
  To: guix-devel

Hi Guix,

given that Shepherd 0.9.0 adds support for systemd-style socket
activation and Emacs supports that (if linked against systemd!) I
wanted to try it out.  Here's my "generic" recipe for constructing
an Emacs service:

--8<---------------cut here---------------start------------->8---
(define* (emacs #:key (name 'server)
                (uid (getuid))
                (gid (getgid)))
  (make <service>
    #:provides (list
                (symbol-append 'emacs@ name))
    #:requires '()
    #:start
    (make-systemd-constructor
     (list "emacs" "--fg-daemon")
     (list (endpoint
            (make-socket-address AF_UNIX
                                 (format #f "/run/user/~d/emacs/~s"
                                         uid name))
            #:socket-owner uid
            #:socket-group gid)))
    #:stop (make-systemd-destructor)))
--8<---------------cut here---------------end--------------->8---

Note how this allows the creation of multiple sockets, that launch
Emacsen on demand.  For instance, I could hook up one Emacs to git
changelogs, one mail reading and one to writing prose without them
interfering with each other.  (This assumes that tools spawing Emacs
will correctly launch emacsclient, of course.)  If for some reason,
I am not writing that many changelogs one day, the git one doesn't
need to be spawned, and so on, and so forth.

Sadly, this doesn't work as intended currently.  You will have to
use a specially prepared emacs, that links against systemd (logind
works fine too, use the recipe below).  I plan to upstream these
changes soon™, given that we're also lagging behind on Emacs 28.

--8<---------------cut here---------------start------------->8---
(define emacs-with-systemd
  (package (inherit emacs)
           (arguments
            (substitute-keyword-arguments
             (package-arguments emacs)
             ((#:phases phases)
              #~(modify-phases #$phases
                  (add-after 'unpack 'enable-logind
                    (lambda _
                      (substitute* (list "configure.ac")
                        (("libsystemd") "libelogind"))
                      (delete-file "configure")))))))
           (inputs (modify-inputs (package-inputs emacs)
                                  (prepend elogind)))
           (native-inputs (modify-inputs (package-native-inputs emacs)
                                         (prepend autoconf)))))
--8<---------------cut here---------------end--------------->8---

There appear to be some bugs, though.  If shepherd launches a process
via systemd-constructor and it dies before claiming the socket, it
will become a zombie.  Further, if the process dies after having
claimed the socket, shepherd will not reset service's entry points and
running value.  Both should be fixable in my opinion.

So, what's for the future?  If someone wants to do so, they could
adapt my shepherd service for Guix Home.  It'd be very nice to one
day be able to spawn an Emacs service fine-tuned to desired editing
purposes.  Think of using `guix shell --container' building packages
that you'd otherwise rarely need on demand, for example.

With that in mind, happy hacking!


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Sockets in Shepherd, and Emacs, oh my!
  2022-04-08 18:40 Sockets in Shepherd, and Emacs, oh my! Liliana Marie Prikler
@ 2022-04-10 20:40 ` Ludovic Courtès
  2022-04-11  4:23   ` Liliana Marie Prikler
  0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2022-04-10 20:40 UTC (permalink / raw)
  To: Liliana Marie Prikler; +Cc: guix-devel

Hallo!

Liliana Marie Prikler <liliana.prikler@gmail.com> skribis:

> given that Shepherd 0.9.0 adds support for systemd-style socket
> activation and Emacs supports that (if linked against systemd!) I
> wanted to try it out.  Here's my "generic" recipe for constructing
> an Emacs service:
>
> (define* (emacs #:key (name 'server)
>                 (uid (getuid))
>                 (gid (getgid)))
>   (make <service>
>     #:provides (list
>                 (symbol-append 'emacs@ name))
>     #:requires '()
>     #:start
>     (make-systemd-constructor
>      (list "emacs" "--fg-daemon")
>      (list (endpoint
>             (make-socket-address AF_UNIX
>                                  (format #f "/run/user/~d/emacs/~s"
>                                          uid name))
>             #:socket-owner uid
>             #:socket-group gid)))
>     #:stop (make-systemd-destructor)))

Fun!  Good to see this put to good use.  :-)

> There appear to be some bugs, though.  If shepherd launches a process
> via systemd-constructor and it dies before claiming the socket, it
> will become a zombie.

What do you mean by “claiming the socket”?  Do you have a log file
showing this, or at (better yet) a small reproducer?  You can use
‘tests/systemd.sh’ as a starting point.

> Further, if the process dies after having claimed the socket, shepherd
> will not reset service's entry points and running value.  Both should
> be fixable in my opinion.

The running value is changed as soon as the child process is started by
‘make-systemd-constructor’, AFAICS.  But maybe I’m overlooking
something.

> So, what's for the future?  If someone wants to do so, they could
> adapt my shepherd service for Guix Home.  It'd be very nice to one
> day be able to spawn an Emacs service fine-tuned to desired editing
> purposes.  Think of using `guix shell --container' building packages
> that you'd otherwise rarely need on demand, for example.
>
> With that in mind, happy hacking!

Sounds fun!

Ludo’.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Sockets in Shepherd, and Emacs, oh my!
  2022-04-10 20:40 ` Ludovic Courtès
@ 2022-04-11  4:23   ` Liliana Marie Prikler
  2022-04-18 19:43     ` Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Liliana Marie Prikler @ 2022-04-11  4:23 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Hi,

Am Sonntag, dem 10.04.2022 um 22:40 +0200 schrieb Ludovic Courtès:
> Hallo!
> 
> Liliana Marie Prikler <liliana.prikler@gmail.com> skribis:
> 
> > given that Shepherd 0.9.0 adds support for systemd-style socket
> > activation and Emacs supports that (if linked against systemd!) I
> > wanted to try it out.  Here's my "generic" recipe for constructing
> > an Emacs service:
> > 
> > (define* (emacs #:key (name 'server)
> >                 (uid (getuid))
> >                 (gid (getgid)))
> >   (make <service>
> >     #:provides (list
> >                 (symbol-append 'emacs@ name))
> >     #:requires '()
> >     #:start
> >     (make-systemd-constructor
> >      (list "emacs" "--fg-daemon")
> >      (list (endpoint
> >             (make-socket-address AF_UNIX
> >                                  (format #f "/run/user/~d/emacs/~s"
> >                                          uid name))
> >             #:socket-owner uid
> >             #:socket-group gid)))
> >     #:stop (make-systemd-destructor)))
Addendum: This only worked, because I had the directory already
created.  For the directory to be created with the correct permissions,
you need to add #:socket-directory-permissions #o700.

> Fun!  Good to see this put to good use.  :-)
> 
> > There appear to be some bugs, though.  If shepherd launches a
> > process via systemd-constructor and it dies before claiming the
> > socket, it will become a zombie.
> 
> What do you mean by “claiming the socket”?  Do you have a log file
> showing this, or at (better yet) a small reproducer?  You can use
> ‘tests/systemd.sh’ as a starting point.
Emacs without systemd support simply exits, because Shepherd owns the
socket.  I think a rather simple command that exits immediately or
after sleep 5 ought to do the trick.

> > Further, if the process dies after having claimed the socket,
> > shepherd will not reset service's entry points and running value. 
> > Both should be fixable in my opinion.
> 
> The running value is changed as soon as the child process is started
> by ‘make-systemd-constructor’, AFAICS.  But maybe I’m overlooking
> something.
Sure, but in neither case appears the dying process to be handled
correctly.  If shepherd doesn't check whether the service takes over,
it might even be the same bug, but I didn't check if the correctly
spawned emacs becomes a zombie.  At the very least I'd argue it'd be
cleaned up during manual service restart, which is needed to get your
socket back.

> 
Cheers


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Sockets in Shepherd, and Emacs, oh my!
  2022-04-11  4:23   ` Liliana Marie Prikler
@ 2022-04-18 19:43     ` Ludovic Courtès
  2022-04-18 21:14       ` Liliana Marie Prikler
  0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2022-04-18 19:43 UTC (permalink / raw)
  To: Liliana Marie Prikler; +Cc: guix-devel

Hi,

Liliana Marie Prikler <liliana.prikler@gmail.com> skribis:

> Am Sonntag, dem 10.04.2022 um 22:40 +0200 schrieb Ludovic Courtès:

[...]

>> What do you mean by “claiming the socket”?  Do you have a log file
>> showing this, or at (better yet) a small reproducer?  You can use
>> ‘tests/systemd.sh’ as a starting point.
> Emacs without systemd support simply exits, because Shepherd owns the
> socket.  I think a rather simple command that exits immediately or
> after sleep 5 ought to do the trick.

Hmm could you share such a reproducer?  I’m not sure I understand.

A useful source of inspiration to write a reproducer might be this test:

  https://git.savannah.gnu.org/cgit/shepherd.git/tree/tests/systemd.sh

TIA!

Ludo’.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Sockets in Shepherd, and Emacs, oh my!
  2022-04-18 19:43     ` Ludovic Courtès
@ 2022-04-18 21:14       ` Liliana Marie Prikler
  2022-04-20  9:50         ` Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Liliana Marie Prikler @ 2022-04-18 21:14 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Am Montag, dem 18.04.2022 um 21:43 +0200 schrieb Ludovic Courtès:
> Hi,
> 
> Liliana Marie Prikler <liliana.prikler@gmail.com> skribis:
> 
> > Am Sonntag, dem 10.04.2022 um 22:40 +0200 schrieb Ludovic Courtès:
> 
> [...]
> 
> > 
> > > What do you mean by “claiming the socket”?  Do you have a log
> > > file showing this, or at (better yet) a small reproducer?  You
> > > can use ‘tests/systemd.sh’ as a starting point.
> > Emacs without systemd support simply exits, because Shepherd owns
> > the socket.  I think a rather simple command that exits immediately
> > or after sleep 5 ought to do the trick.
> 
> Hmm could you share such a reproducer?  I’m not sure I understand.
Hmm, this test indeed works as intended on master, and when I try to
invoke bad behaviour deliberately in the way I pointed out, it seems to
restart the service cleanly.  I haven't checked the release commit, but
the emacs reproducer would be the following:

A.1 Build Emacs without systemd support.
A.2 Start my emacs service.
A.3 Launch emacsclient (due to emacs dying, emacsclient should either
die or loop forever/until a timeout, can't remember)
A.4 Launch emacsclient again.

B.1 Build Emacs with systemd support
B.2 Start my emacs service
B.3 Launch emacsclient (due to emacs supporting systemd, emacsclient
should run)
B.4 Use M-x kill-emacs to kill the emacs service.
B.5 Launch emacsclient again (it should fail to launch)

Thinking about it some more, I am probably dumb and forgot #:respawn?
#t.  Looking at my mail, it most definitely seems as though I did. 
Well, that's a lesson learned, #:respawn? is #f normally.

Cheers


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Sockets in Shepherd, and Emacs, oh my!
  2022-04-18 21:14       ` Liliana Marie Prikler
@ 2022-04-20  9:50         ` Ludovic Courtès
  0 siblings, 0 replies; 6+ messages in thread
From: Ludovic Courtès @ 2022-04-20  9:50 UTC (permalink / raw)
  To: Liliana Marie Prikler; +Cc: guix-devel

Hi,

Liliana Marie Prikler <liliana.prikler@gmail.com> skribis:

> Thinking about it some more, I am probably dumb and forgot #:respawn?
> #t.  Looking at my mail, it most definitely seems as though I did. 
> Well, that's a lesson learned, #:respawn? is #f normally.

Oh right, you need #:respawn? #t if you want it to be respawned.

Anyway, if you have other suspicions of things not working correctly, a
small reproducer is always welcome.

Thanks for checking!

Ludo’.


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-04-20  9:51 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-04-08 18:40 Sockets in Shepherd, and Emacs, oh my! Liliana Marie Prikler
2022-04-10 20:40 ` Ludovic Courtès
2022-04-11  4:23   ` Liliana Marie Prikler
2022-04-18 19:43     ` Ludovic Courtès
2022-04-18 21:14       ` Liliana Marie Prikler
2022-04-20  9:50         ` Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).