fix(demo): kill launcher process groups and trap before creating the work dir
3 files · +9 -4
M docs/media/demo.mp4 +0 -0 binary file: no text diff
binary file: no text diff
M docs/media/demo.png +0 -0 binary file: no text diff
binary file: no text diff
M tools/demo/record.sh +9 -4
| @@ -9,16 +9,17 @@ for command in docker go ffmpeg; do | |||
| 9 | 9 | done | |
| 10 | 10 | docker info >/dev/null 2>&1 || { echo 'Docker daemon unavailable; start rootless Docker first.' >&2; exit 1; } | |
| 11 | 11 | work=$(mktemp -d "${TMPDIR:-/tmp}/neferwl-demo.XXXXXX") | |
| 12 | - | printf 'Capture directory: %s\n' "$work" | |
| 13 | - | mkdir -p "$work/shots" docs/media | |
| 14 | 12 | compositor='' launcher='' feeder='' success='' | |
| 15 | 13 | container=neferwl-demo-$$ | |
| 16 | 14 | cleanup() { | |
| 17 | 15 | local status=$? | |
| 18 | 16 | trap - EXIT | |
| 19 | - | for pid in "$launcher" "$feeder" "$compositor"; do | |
| 20 | - | if [[ -n $pid ]]; then kill "$pid" 2>/dev/null || true; fi | |
| 17 | + | # launcher and feeder run with job control (set -m) in their own process | |
| 18 | + | # groups, so killing the group also stops their sleep/docker exec children. | |
| 19 | + | for pid in "$launcher" "$feeder"; do | |
| 20 | + | if [[ -n $pid ]]; then kill -- "-$pid" 2>/dev/null || kill "$pid" 2>/dev/null || true; fi | |
| 21 | 21 | done | |
| 22 | + | if [[ -n $compositor ]]; then kill "$compositor" 2>/dev/null || true; fi | |
| 22 | 23 | docker rm -f "$container" >/dev/null 2>&1 || true | |
| 23 | 24 | for pid in "$launcher" "$feeder" "$compositor"; do | |
| 24 | 25 | if [[ -n $pid ]]; then wait "$pid" 2>/dev/null || true; fi | |
| @@ -32,6 +33,8 @@ cleanup() { | |||
| 32 | 33 | trap cleanup EXIT | |
| 33 | 34 | trap 'exit 130' INT | |
| 34 | 35 | trap 'exit 143' TERM | |
| 36 | + | printf 'Capture directory: %s\n' "$work" | |
| 37 | + | mkdir -p "$work/shots" docs/media | |
| 35 | 38 | docker build -t neferwl-demo -f tools/demo/Dockerfile tools/demo | |
| 36 | 39 | CGO_ENABLED=0 go build -o "$work/neferwl" ./cmd/neferwl | |
| 37 | 40 | state=$work/state | |
| @@ -86,10 +89,12 @@ docker exec -d --user demo "$container" foot --title 'System / NeferWL' bash -c | |||
| 86 | 89 | # The first app is launched before t=0. FIFO input and shell launches now | |
| 87 | 90 | # share this epoch, independent of compositor/image/container startup time. | |
| 88 | 91 | SECONDS=0 | |
| 92 | + | set -m | |
| 89 | 93 | { cat tools/demo/input.txt; printf '\nkey Ctrl+Alt+BackSpace\n'; } >&3 & | |
| 90 | 94 | feeder=$! | |
| 91 | 95 | launch_apps & | |
| 92 | 96 | launcher=$! | |
| 97 | + | set +m | |
| 93 | 98 | # --timeout exits nonzero; accept only its explicit timeout log entry. | |
| 94 | 99 | if ! wait "$compositor"; then | |
| 95 | 100 | grep -q '"reason":"timeout"' "$log" || exit 1 | |
| @@ -9,16 +9,17 @@ for command in docker go ffmpeg; do | |||||
| 9 | done | 9 | done | ||
| 10 | docker info >/dev/null 2>&1 || { echo 'Docker daemon unavailable; start rootless Docker first.' >&2; exit 1; } | 10 | docker info >/dev/null 2>&1 || { echo 'Docker daemon unavailable; start rootless Docker first.' >&2; exit 1; } | ||
| 11 | work=$(mktemp -d "${TMPDIR:-/tmp}/neferwl-demo.XXXXXX") | 11 | work=$(mktemp -d "${TMPDIR:-/tmp}/neferwl-demo.XXXXXX") | ||
| 12 | - | printf 'Capture directory: %s\n' "$work" | |||
| 13 | - | mkdir -p "$work/shots" docs/media | |||
| 14 | compositor='' launcher='' feeder='' success='' | 12 | compositor='' launcher='' feeder='' success='' | ||
| 15 | container=neferwl-demo-$$ | 13 | container=neferwl-demo-$$ | ||
| 16 | cleanup() { | 14 | cleanup() { | ||
| 17 | local status=$? | 15 | local status=$? | ||
| 18 | trap - EXIT | 16 | trap - EXIT | ||
| 19 | - | for pid in "$launcher" "$feeder" "$compositor"; do | 17 | + | # launcher and feeder run with job control (set -m) in their own process |
| 20 | - | if [[ -n $pid ]]; then kill "$pid" 2>/dev/null || true; fi | 18 | + | # groups, so killing the group also stops their sleep/docker exec children. |
| 19 | + | for pid in "$launcher" "$feeder"; do | |||
| 20 | + | if [[ -n $pid ]]; then kill -- "-$pid" 2>/dev/null || kill "$pid" 2>/dev/null || true; fi | |||
| 21 | done | 21 | done | ||
| 22 | + | if [[ -n $compositor ]]; then kill "$compositor" 2>/dev/null || true; fi | |||
| 22 | docker rm -f "$container" >/dev/null 2>&1 || true | 23 | docker rm -f "$container" >/dev/null 2>&1 || true | ||
| 23 | for pid in "$launcher" "$feeder" "$compositor"; do | 24 | for pid in "$launcher" "$feeder" "$compositor"; do | ||
| 24 | if [[ -n $pid ]]; then wait "$pid" 2>/dev/null || true; fi | 25 | if [[ -n $pid ]]; then wait "$pid" 2>/dev/null || true; fi | ||
| @@ -32,6 +33,8 @@ cleanup() { | |||||
| 32 | trap cleanup EXIT | 33 | trap cleanup EXIT | ||
| 33 | trap 'exit 130' INT | 34 | trap 'exit 130' INT | ||
| 34 | trap 'exit 143' TERM | 35 | trap 'exit 143' TERM | ||
| 36 | + | printf 'Capture directory: %s\n' "$work" | |||
| 37 | + | mkdir -p "$work/shots" docs/media | |||
| 35 | docker build -t neferwl-demo -f tools/demo/Dockerfile tools/demo | 38 | docker build -t neferwl-demo -f tools/demo/Dockerfile tools/demo | ||
| 36 | CGO_ENABLED=0 go build -o "$work/neferwl" ./cmd/neferwl | 39 | CGO_ENABLED=0 go build -o "$work/neferwl" ./cmd/neferwl | ||
| 37 | state=$work/state | 40 | state=$work/state | ||
| @@ -86,10 +89,12 @@ docker exec -d --user demo "$container" foot --title 'System / NeferWL' bash -c | |||||
| 86 | # The first app is launched before t=0. FIFO input and shell launches now | 89 | # The first app is launched before t=0. FIFO input and shell launches now | ||
| 87 | # share this epoch, independent of compositor/image/container startup time. | 90 | # share this epoch, independent of compositor/image/container startup time. | ||
| 88 | SECONDS=0 | 91 | SECONDS=0 | ||
| 92 | + | set -m | |||
| 89 | { cat tools/demo/input.txt; printf '\nkey Ctrl+Alt+BackSpace\n'; } >&3 & | 93 | { cat tools/demo/input.txt; printf '\nkey Ctrl+Alt+BackSpace\n'; } >&3 & | ||
| 90 | feeder=$! | 94 | feeder=$! | ||
| 91 | launch_apps & | 95 | launch_apps & | ||
| 92 | launcher=$! | 96 | launcher=$! | ||
| 97 | + | set +m | |||
| 93 | # --timeout exits nonzero; accept only its explicit timeout log entry. | 98 | # --timeout exits nonzero; accept only its explicit timeout log entry. | ||
| 94 | if ! wait "$compositor"; then | 99 | if ! wait "$compositor"; then | ||
| 95 | grep -q '"reason":"timeout"' "$log" || exit 1 | 100 | grep -q '"reason":"timeout"' "$log" || exit 1 | ||