it’s been awhile since we had this thread [1] about running multiple processes as a single app. this use case has come again recently. maybe you want to run an agent along side your app in a separate process. maybe you need redis embedded with your app. there are many reasons you might have a multi-process app.
the way cloud foundry apps work now is that the DEA is watching the Warden container for a single OS process per cloud foundry app, so if a parent process spins off 2 child processes A and B, and child processes A is required for child process B to work properly, then you want the DEA/Warden/Health Manager to restart the entire app in a new app container when any of the required child processes fail, not to wait until all child processes have finished.
david supplied a bash start.sh
script [2] that can act as a parent process and watch child processes as well as a more polished solution using forego [3] (a golang version of foreman). forego does a nice job of aggregating the stdout/stderr for the child processes into the parent process stdout/stderr with nice color formatting. you can see this by running forego start
in the eg
dir example in the forego repo [4]. forego is certainly a nice elegant and simple solution, but you have to either package the 6MB forego binary with your app or have a buildpack that will either download it or compile it during the compile buildpack phase.
as a simple bash alternative to forego, i found that david’s linked example bash start.sh
script did not actually exit when a single child processes exited, rather it waited until all child processes exited. so i put together a little bash script called startAndExitOnAnyChildExit.sh [5] that takes a lists of processes to run and exit all including the parent when any child processes exits. it uses SIGTERM first and gives all child processes 2 seconds to exit nicely, then sends SIGKILL for any child processes that didn't exit nicely.
example usage. let’s say you have two processes, a sleep process and a ticker process [6]. the ticker process is configured to ignore TERM signals, so you need to send it a KILL.
in terminal 1:./startAndExitOnAnyChildExit.sh 'sleep 60' './ticker'
then kill the PID from the sleep in terminal 2, and you should something like this:
$ ./startAndExitOnAnyChildExit.sh 'sleep 60' './ticker'
Process "sleep 60" started with pid 58761
Process "./ticker" started with pid 58762
tick: [] -- FOO:
tick: [] -- FOO:
tick: [] -- FOO:
tick: [] -- FOO:
./startAndExitOnAnyChildExit.sh: line 26: 58761 Terminated: 15 $cmd
child process 58761 exited, killing all children and exiting
sending TERM to 58762
received SIGTERM but i'm ignoring it!
tick: [] -- FOO:
tick: [] -- FOO:
sending KILL to 58762
so you should be able to include this bash process in your cloud foundry app and then make the start command something like:/app/startAndExitOnAnyChildExit.sh /app/child-process1.sh /app/child-process2.sh
[1] https://groups.google.com/a/cloudfoundry.org/d/msg/vcap-dev/OHbSH6gOAOQ/UU63UD_DHSYJ
[2] https://github.com/cityindex/logsearch-flowdock-bot/blob/1d961eb6829b3d682229a3cfd9b58fa3181a69c9/start.sh
[3] https://github.com/ddollar/forego
[4] https://www.evernote.com/shard/s3/sh/7aa5a17d-b5f9-4063-9199-8ad9a5da5bd1/d0898f2aac5458df61f3b53a4697d3af
[5] https://gist.github.com/jbayer/8368233
James,
Cool update!
I shall be rolling that back into my projects!
D
To unsubscribe from this group and stop receiving emails from it, send an email to vcap-dev+u...@cloudfoundry.org.