With the previous way systemd services were exported, you had to enable every single process one by one to get the service operational.
Consider the following Procfile:
web: bundle exec thin start
worker: bundle exec worker start
Exported with:
foreman export systemd /usr/lib/systemd/system -a myapp -c worker=3
You will have to perform the following to start the service:
systemctl enable myapp-web-1.service
systemctl enable myapp-worker-1.service
systemctl enable myapp-worker-2.service
systemctl enable myapp-worker-3.service
systemctl enable myapp-web.target
systemctl enable myapp-worker.target
systemctl start myapp.target
Thats 7 commands, and you have to know the names of each service. Nasty.
With the changes here, you will have to perform the following:
systemctl enable myapp.target
systemctl start myapp.target
You can also `systemctl start myapp.target` without enabling as well. Previously if you tried to start `myapp.target` without enabling each individual process it would not work.
---
Additionally, this change also adds the dependency to 'multi-user.target' (the default behavior for all services). This will properly shut down (or start) the app when the system changes runlevels. The previous method did not do this.
This removes the fork when doing `foreman run`. The fork results in an unnecessary process laying around. The parent process doesn't do anything other than fork and wait for the child to exit.
This is a better fix for several reasons:
- It's more portable; the arguments/options to 'ps' vary widely across
platforms.
- Killing children by forking yet more children (i.e., via backtick) is
problematic when you're trying to kill processes because of resource
starvation.
- Processes should not signal processes other than their own children,
especially in a generic task-runner like Foreman. If the signal
should propagate, then the sub-process should propagate signals to its
children itself. There's no way to know what cleanup or preparation
is necessary for a clean shutdown (e.g., SIGINT/SIGTERM), and
in what order grandchild processes should be shut down to properly
release locks, close files, etc.
- foreman-runner doesn't (shouldn't?) create grandchild processes; the
last thing it does is `exec` the program it's launching, which
will replace the program of the *current* process with the one
being started up.