We want to be able to start hyper-gateway from one Emacs instance and close it from another instance. This means that stopping the process is more complicated that killing the PID, since the new Emacs instance doesn't know the PID. The current solution is to store the hyper-gateway command path as hyper-gateway-command
and find the running the process with pgrep.
This pgrep approach is fragile since the binary name could be wrong or the port could be wrong. Allowing the user to set both the binary name and the port means an additional step users have to keep track of.
How do other Emacs packages handle shared services between Emacs instances? Should we use system services?
For interacting with
mpd
, both emms and simple-mpc expect the user to start and stop the daemon outside of Emacs.Where else might we look for inspiration?
This is an interesting problem. Looking at the example of MPD, nowadays on Linux systems, that would typically be handed by a systemd unit, probably starting the daemon when a user logs in (though MPD can be configured for system-wide use, in which case it could be started at boot time, but that would be up to the user).
I'm still new to Hypercore and Hyperdrive, and I need to learn more about your goals for the Emacs-based UI. But generally, I would lean toward setting up the daemon outside of Emacs, if possible. AFAIK, systemd is mature in this respect, and I'd guess that the daemon should keep running to share files even if the user exits Emacs; and I'd guess that, if the user really wants to share some files persistently, the daemon should be running even if the user hasn't started Emacs. So while it would be helpful to have some kind of Emacs commands to ensure that the daemon is running and terminate it, I'd guess it would be best if Emacs weren't required to start the daemon.
Of course, another question is that of platform. If hyper-gateway is intended to work on non-Linux platforms, that would add a lot of complexity in this regard. It will have to be accounted for somewhere, whether in the Emacs package or in hyper-gateway itself. And even systemd is not necessarily universal on Linux.
So maybe a good first step would be to clearly define the goals and targeted platforms--for my sake, at least, since I'm new. :)
Thank you, Adam!
"~alphapapa" outgoing@sr.ht writes:
This is an interesting problem. Looking at the example of MPD, nowadays on Linux systems, that would typically be handed by a systemd unit, probably starting the daemon when a user logs in (though MPD can be configured for system-wide use, in which case it could be started at boot time, but that would be up to the user).
I'm still new to Hypercore and Hyperdrive, and I need to learn more about your goals for the Emacs-based UI. But generally, I would lean toward setting up the daemon outside of Emacs, if possible. AFAIK, systemd is mature in this respect, and I'd guess that the daemon should keep running to share files even if the user exits Emacs; and I'd guess that, if the user really wants to share some files persistently, the daemon should be running even if the user hasn't started Emacs. So while it would be helpful to have some kind of Emacs commands to ensure that the daemon is running and terminate it, I'd guess it would be best if Emacs weren't required to start the daemon.
I agree that the daemon should not depend on Emacs and also that we should be able to start and stop it from within Emacs.
Of course, another question is that of platform. If hyper-gateway is intended to work on non-Linux platforms, that would add a lot of complexity in this regard. It will have to be accounted for somewhere, whether in the Emacs package or in hyper-gateway itself. And even systemd is not necessarily universal on Linux.
hyper-gateway
has releases which run on Windows and macOS.So maybe a good first step would be to clearly define the goals and targeted platforms--for my sake, at least, since I'm new. :)
Yes, good idea! Let's focus on GNU/Linux and multiple init systems. On other platforms,
hyper-gateway
can be started and stopped manually.Do you think it makes sense to use https://github.com/cbowdon/daemons.el ?
Yes, good idea! Let's focus on GNU/Linux and multiple init systems. On other platforms, hyper-gateway can be started and stopped manually.
Okay. I'd further suggest that we support only one init system to begin with (i.e. probably systemd), because there are a variety of them on GNU/Linux distros now, and it's likely that users who don't use the default (i.e. probably systemd) will have the ability to handle setting up a service in their system of choice. Generally, the more we commit to supporting, the more we'll have to fix bugs and answer support questions in the future as things inevitably change.
Do you think it makes sense to use https://github.com/cbowdon/daemons.el ?
I looked at that repo briefly. On a first glance, its code appears to be pretty good. However, it's on MELPA and hasn't been updated in about 3 years, so I'd recommend that we do not depend on it.
Instead, what I'd suggest is something like this:
hyper-gateway
should offer users directions for setting up a systemd service (e.g. a.service
file/unit, as appropriate). That should include allowing the service to run per-user (rather than as root and requiring root permissions to start/stop). (Aside: This will likely also allow us to detect whether the service is running; I think systemd has provisions for that sort of thing.)hyperdrive.el
should offer a simple command to start/stop the per-user systemd service.IMHO that's the simplest way to proceed, and it should minimize the necessary work and configuration for all parties.
Okay. I'd further suggest that we support only one init system to begin with (i.e. probably systemd), because there are a variety of them on GNU/Linux distros now, and it's likely that users who don't use the default (i.e. probably systemd) will have the ability to handle setting up a service in their system of choice. Generally, the more we commit to supporting, the more we'll have to fix bugs and answer support questions in the future as things inevitably change.
Sure, that sounds good.
Do you think it makes sense to use https://github.com/cbowdon/daemons.el ?
I looked at that repo briefly. On a first glance, its code appears to be pretty good. However, it's on MELPA and hasn't been updated in about 3 years, so I'd recommend that we do not depend on it.
Sounds good also.
Instead, what I'd suggest is something like this:
hyper-gateway
should offer users directions for setting up a systemd service (e.g. a.service
file/unit, as appropriate). That should include allowing the service to run per-user (rather than as root and requiring root permissions to start/stop). (Aside: This will likely also allow us to detect whether the service is running; I think systemd has provisions for that sort of thing.)hyperdrive.el
should offer a simple command to start/stop the per-user systemd service.IMHO that's the simplest way to proceed, and it should minimize the necessary work and configuration for all parties.
Let's get Mauve's input on this addition to
hyper-gateway
.
Pending resolution of https://github.com/RangerMauve/hyper-gateway/issues/7 , add a function
hyperdrive-setup
, which
- Returns early if
hyper-gateway
is already running (hyperdrive--gateway-ready-p
)- Downloads
hyper-gateway
binary, moves it intoPATH
(~/.local/bin/
?),chmod u+x
it- Runs bash script to set up user-level systemd service file
Also, add instructions to the README for manually doing this.
Also, we should add a check to ensure that we're using the latest version of
hyper-gateway
.
I dug through the systemd documentation, wrote a service file, tested it, and wrote these instructions:
Make service file:
Place in directory
~/.local/share/systemd/user
(or$XDG_DATA_HOME/systemd/user/
).Using filename
hyper-gateway.service
.These contents:
[Unit] Description=hypercore-protocol gateway daemon (for hyperdrive) Documentation=https://github.com/RangerMauve/hyper-gateway ; FIXME: Requisite=network.service ? or BindsTo=? or After=? [Service] Type=exec ExecStart=%h/.local/bin/hyper-gateway --writable true --silent true run
Run
systemctl --user daemon-reload
to reload the service file.Run
systemctl --user start hyper-gateway.service
to start the service.Run
systemctl --user status hyper-gateway.service
to view the service's status.Run
systemctl --user stop hyper-gateway.service
to stop the service.It works for starting and stopping the service.
A few notes:
- We pass
--silent true
to the daemon, because we don't want to log HTTP requests to the journal.- We could consider specifying dependency information so the user could have the service started automatically, e.g. when the network is up. That line could be commented out by default, or we could suggest that the user write a separate config file to the appropriate filename so this
hyper-gateway.service
file could remain the same as in our documentation.The next step is to simply change the
hyperdrive-start
/-stop
commands in Emacs to callsystemctl --user start/stop hyper-gateway.service
. And we could add a command to check its status as well.Another possible enhancement would be to configure the service file to check that the network socket is open by the daemon, but that's probably not necessary, since it starts so quickly.
Great work!
I wondered about the lack of
ExecStop=
, but according to this SO post, the default is to sendSIGTERM
, which is fine forhyper-gateway
.I went ahead and updated the
hyperdrive-start
andhyperdrive-stop
functions. I also addedhyperdrive--active-p
to check if the service is running andhyperdrive-status
to interactively echo that information.Another possible enhancement would be to configure the service file to check that the network socket is open by the daemon, but that's probably not necessary, since it starts so quickly.
I agree that this is not necessary for now.
Would you be willing to make a PR to hyper-gateway to add these instructions to that repo?
I submitted the PR here. Thank you, Adam!! Once that's resolved, the next step is to add instructions on this README to direct users over to the hyper-gateway instructions.
As of dfbf830 , the README.me directs users to installation instructions here.