0

I'm currently writing a python app forking with Pyro4 and flask. In order to start up the app I to need :

  1. Start pyro4 name server
  2. Register my object in the pyro4 name server
  3. Start a flask web app to access pyro4 objects

I would like to do this with a systemd service file. I first though of using ExecStarPre and ExecStarPost for running pyro4 nameserver and flask web app ; but it seems that those fields are not use for long-running commands...

Do I need to make 3 systemd services which I start in a bash script that i call from a 4th systemd service ?

Thx for helping me

I'm trying to write a systemd service file

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • What do you mean "not use for long command"? There's no artificial limit on the length of those commands (which is not to say using them for this purpose is a good idea). – Charles Duffy Feb 14 '22 at 00:47
  • Also, no, you don't need a 4th systemd service that starts a bash script that starts the other services -- in general, you should _never_ call `systemctl start` on one service from any other systemd service; instead, you should simply set up dependencies between those services. – Charles Duffy Feb 14 '22 at 00:48
  • ...the important question here is whether you can register your service in Pyro _before your service has started_. – Charles Duffy Feb 14 '22 at 00:52
  • For "not use for long command" I mean that I need to run pyro4 name server before registering my object in the pyro4 name server and starting my mainloop. This command will not return until the end of pyro4 ns process so I won't be able to load the rest of my app – Febvre Antoine Feb 14 '22 at 00:54
  • Do you mean the _register_ command won't return until after the nameserver exits? Please be explicit -- I know systemd, but not pyro, so I can only give you a good answer if you fill in all the pyro-specific details. – Charles Duffy Feb 14 '22 at 00:55
  • I need to start pyro ns before registering any objects ; then I register anything I need in the pyro ns and start pyro main serving loop ; then i finally start my web app to access those pyro object in the pyro ns – Febvre Antoine Feb 14 '22 at 00:56
  • Right, I understand that; the question is how long the register command (not the name service, but only the registration operation) runs. – Charles Duffy Feb 14 '22 at 00:56
  • (basically, you need a separate service for long-running commands; short-running commands it's optional -- sometimes there's a good reason to make a separate service for them, but often they can be folded into pre or post commands). – Charles Duffy Feb 14 '22 at 00:58
  • All 3 are long running command ; the first serve the pyo name server itself ; the second serve my custom objects registered in pyro ; and the 3rd serve the web app – Febvre Antoine Feb 14 '22 at 01:01
  • Okay, in that case you really do need three services; just use `Requires=` and `After=` to set up the ordering between them. – Charles Duffy Feb 14 '22 at 01:02
  • BTW, one thing that's a little tricky is controlling when systemd considers something to be "up" for purposes of starting the next service in the chain. In a perfect would you have services that use `sd_notify()` to tell systemd when they finished initialization; but if you haven't built that, it's an option to build an `ExecStartPost` script that waits until the server is actually running before it exits. – Charles Duffy Feb 14 '22 at 01:05

1 Answers1

1

You don't need four systemd services; three should do.

  • pyro-nameserver.service: The Pyro nameserver
  • mysvc-objects.service: The server for your custom Pyro objects. Use Requires=pyro-nameserver.service and After=pyro-nameserver.service
  • mysvc.service: The actual Flask webapp. Uses Requires=mysvc-objects.service and After=mysvc-objects.service to ensure that it only tries to start when the nameserver is already up and your objects are registered.

You should never, under any circumstances enable or disable a systemd service from an ExecStartPre or an ExecStartPost.

BTW, one thing that's a little tricky is controlling when systemd considers something to be "up" for purposes of starting the next service in the chain only after that service is done with initialization and ready to use. In a perfect would you build services with Type=notify that use sd_notify("READY=1") to tell systemd when they finished initialization; but if you haven't built that, it's an option to build an ExecStartPost script that waits until the service it's associated with is actually running before it exits.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441