logger: Add --sh-syntax, --background
-
utils: Add _srt_string_read_fd_until_eof—applied -
utils: Add _srt_string_ends_with—applied -
logger: Fix incorrect function arguments in a doc-comment
-
logger: Add a mechanism to report when the logger is ready
When launching the logger in the background from a shell script, its exit status will not always be available. There are three states we need to signal to the caller: preparing, ready, and failed.
A caller can distinguish between preparing and ready/failed by polling and reading standard output until EOF: until EOF is reached, the logger is still preparing, and after EOF is reached, it is ready. But that doesn't tell the caller whether startup was successful or not.
If the logger crashes before it has had a chance to send anything on standard output, then standard output will be closed with no further data; so we need to signal success by sending something non-empty. Use shell syntax, so that we will be able to extend the format to provide information to shell scripts such as
steam.sh
.steamrt/tasks#460, steamrt/tasks#461
-
test-logger: Exercise --sh-syntax
-
test-logger: Assert there is no stdout when we don't use --sh-syntax
-
logger: Add --background option
Making the long-running logging process daemonize is necessary to avoid some failure modes when combined with steam-runtime-supervisor.
Without this option, if we run a process inside a supervisor that will passively wait for child processes, and we want a srt-logger to log the output of the supervisor and all of the supervised processes:
srt-logger -d ~/tmp -t supervised-shell -- \ steam-runtime-supervisor --subreaper -- \ sh -c 'echo "placeholder process $$ exiting"'
then we have a deadlock. The logging process that was started internally by srt-logger becomes a child of the steam-runtime-supervisor, which means the supervisor will not exit until after the logger does. Meanwhile, the logger is receiving the supervisor's stdout/stderr via a pipe, so it will not exit until after the supervisor does, a cyclic dependency that results in neither one exiting.
We can break the deadlock by using the new --background option:
srt-logger --background -d ~/tmp -t supervised-shell -- \ steam-runtime-supervisor --subreaper -- \ sh -c 'echo "placeholder process $$ exiting"'
which makes the internal logging process daemonize (double-fork), reparenting itself to a "larger" subreaper if present, or to process 1; either way, the supervisor no longer needs to wait for it.
Similarly, if we set up the same scenario, but this time we want the supervisor to terminate any leaked background processes (such as the sleep(1) process in this example) after the main process exits:
srt-logger -d ~/tmp -t supervised-shell -- \ steam-runtime-supervisor --subreaper --terminate-timeout=5 -- \ sh -c 'sleep 3600 & echo "placeholder process $$ exiting"'
then we have broken the deadlock, but at the cost of introducing a loss of log information: the supervisor will send SIGTERM to the logger, which will stop recording log messages, and potentially important log messages from the supervisor or the background processes will not be written to logs or to the terminal.
Again, we can resolve this problem by adding --background to the srt-logger invocation, which takes it outside the supervisor's control.
The complexity cost of putting the srt-logger into the background is not required in all cases, so --background is an option and not the default.
In all examples shown here, the sh(1) process is a placeholder representing an arbitrary "payload": more realistically, it would be a game, or some other component such as steamwebhelper.
steamrt/tasks#460
-
logger: Emit the final process ID before signalling ready
This lets a caller of
srt-logger --background
discover this. This is where it becomes significant that the format of the --sh-syntax pipe allows for multiple lines.steamrt/tasks#461
-
tests: Add adverb --assert-no-children
We'll use this to test srt-logger --background.
-
test-logger: Exercise --background
-
test-logger: Assert that srt-logger and s-r-supervisor can work together
steamrt/tasks#460
Continued in !722 (merged).