~ushin/ushin#13: 
Share hyper-gateway service between Emacs instances

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?

Status
RESOLVED CLOSED
Submitter
~breatheoutbreathein
Assigned to
Submitted
2 years ago
Updated
1 year, 10 months ago
Labels
0.1.0 hyperdrive.el

~breatheoutbreathein 2 years ago

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?

~alphapapa 2 years ago

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. :)

~ushin 2 years ago

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 ?

~alphapapa 1 year, 11 months ago

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:

  1. 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.)
  2. 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.

~ushin 1 year, 11 months ago

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:

  1. 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.)
  2. 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.

~ushin 1 year, 11 months ago*

Pending resolution of https://github.com/RangerMauve/hyper-gateway/issues/7 , add a function hyperdrive-setup, which

  1. Returns early if hyper-gateway is already running (hyperdrive--gateway-ready-p)
  2. Downloads hyper-gateway binary, moves it into PATH (~/.local/bin/?), chmod u+x it
  3. Runs bash script to set up user-level systemd service file

Also, add instructions to the README for manually doing this.

~ushin 1 year, 11 months ago

Also, we should add a check to ensure that we're using the latest version of hyper-gateway.

~ushin closed duplicate ticket #12 1 year, 11 months ago

~ushin closed duplicate ticket #8 1 year, 11 months ago

~alphapapa 1 year, 10 months ago

I dug through the systemd documentation, wrote a service file, tested it, and wrote these instructions:

  1. 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
      
  2. Run systemctl --user daemon-reload to reload the service file.

  3. Run systemctl --user start hyper-gateway.service to start the service.

  4. Run systemctl --user status hyper-gateway.service to view the service's status.

  5. 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 call systemctl --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.

~ushin 1 year, 10 months ago

Great work!

I wondered about the lack of ExecStop=, but according to this SO post, the default is to send SIGTERM, which is fine for hyper-gateway.

I went ahead and updated the hyperdrive-start and hyperdrive-stop functions. I also added hyperdrive--active-p to check if the service is running and hyperdrive-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?

~ushin 1 year, 10 months ago

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.

~ushin REPORTED CLOSED 1 year, 10 months ago

As of dfbf830 , the README.me directs users to installation instructions here.

Register here or Log in to comment, or comment via email.