refactor: extract rescue_transcript helper from close and clean
cmd_close and cmd_clean each rescued <party dir>/log to $HOME/party-<name>-<timestamp>.log before removing the dir, with close's drain poll as the only difference. Share the mechanism in one helper and keep each caller's own messages and control flow.
This commit is contained in:
parent
9980d2918a
commit
45368232b4
1 changed files with 53 additions and 38 deletions
91
party
91
party
|
|
@ -879,6 +879,40 @@ EOF
|
||||||
echo "Party '$name' started. Attach from a fresh shell with: party join $name"
|
echo "Party '$name' started. Attach from a fresh shell with: party join $name"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Rescue <dir>/log to $HOME/party-<name>-<UTC timestamp>.log before the
|
||||||
|
# per-party dir is removed. When drain=1 (cmd_close, right after
|
||||||
|
# kill-server), the pipe-pane `cat` children may still be draining
|
||||||
|
# their last bytes, so poll for two equal size samples (bounded,
|
||||||
|
# integer sleeps only) before moving; cmd_clean's dead-server check
|
||||||
|
# already confirmed nothing is still writing, so it passes drain=0. A
|
||||||
|
# same-filesystem mv is a rename and would keep catching late writes
|
||||||
|
# regardless, but $HOME and PARTY_SOCKET_DIR are commonly different
|
||||||
|
# filesystems (tmpfs /tmp vs a home partition), where mv is copy+unlink
|
||||||
|
# and tail bytes written after the copy started would be lost from the
|
||||||
|
# copy.
|
||||||
|
#
|
||||||
|
# Sets _rt_dest to the destination path on a successful move, or to ''
|
||||||
|
# when there was nothing to rescue. Returns 0 in both those cases; 2
|
||||||
|
# when HOME is unset; 1 when mv failed.
|
||||||
|
rescue_transcript() {
|
||||||
|
_rt_dir="$1" _rt_name="$2" _rt_drain="$3"
|
||||||
|
_rt_dest=''
|
||||||
|
[ -s "$_rt_dir/log" ] || return 0
|
||||||
|
[ -n "$HOME" ] || return 2
|
||||||
|
if [ "$_rt_drain" = 1 ]; then
|
||||||
|
_rt_prev=-1
|
||||||
|
for _rt_i in 1 2 3; do
|
||||||
|
_rt_size=$(wc -c < "$_rt_dir/log")
|
||||||
|
[ "$_rt_size" -eq "$_rt_prev" ] && break
|
||||||
|
_rt_prev="$_rt_size"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
_rt_dest="$HOME/party-$_rt_name-$(date -u '+%Y%m%d-%H%M%S').log"
|
||||||
|
mv "$_rt_dir/log" "$_rt_dest" 2>/dev/null || { _rt_dest=''; return 1; }
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
cmd_close() {
|
cmd_close() {
|
||||||
name=
|
name=
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
|
|
@ -955,38 +989,21 @@ cmd_close() {
|
||||||
|
|
||||||
# Rescue a transcript before the dir vanishes: losing the night's
|
# Rescue a transcript before the dir vanishes: losing the night's
|
||||||
# log to a routine close is exactly the accident class the threat
|
# log to a routine close is exactly the accident class the threat
|
||||||
# model says to prevent. After kill-server the pipe-pane `cat`
|
# model says to prevent. A failed rescue (HOME unset, mv error)
|
||||||
# children are exiting but may still be draining their last bytes,
|
# leaves the party dir in place rather than deleting it out from
|
||||||
# so poll for two equal size samples (bounded, integer sleeps only)
|
# under a promise the message just made; kill-server already ran,
|
||||||
# before moving it. A same-filesystem mv is a rename and would keep
|
# so the party is dead either way, and `party close` (or `party
|
||||||
# catching late writes regardless, but $HOME and PARTY_SOCKET_DIR
|
# clean`) can be re-run once the transcript is off to safety.
|
||||||
# are commonly different filesystems (tmpfs /tmp vs a home
|
if rescue_transcript "$expected_dir" "$name" 1; then
|
||||||
# partition), where mv is copy+unlink and tail bytes written after
|
[ -z "$_rt_dest" ] || echo "party close: transcript saved to $_rt_dest"
|
||||||
# the copy started would be lost from the copy. A failed rescue
|
else
|
||||||
# (HOME unset, mv error) leaves the party dir in place rather than
|
_rt_rc=$?
|
||||||
# deleting it out from under a promise the message just made;
|
if [ "$_rt_rc" -eq 2 ]; then
|
||||||
# kill-server already ran, so the party is dead either way, and
|
|
||||||
# `party close` (or `party clean`) can be re-run once the transcript
|
|
||||||
# is off to safety.
|
|
||||||
if [ -s "$expected_dir/log" ]; then
|
|
||||||
if [ -z "$HOME" ]; then
|
|
||||||
echo "party close: HOME is unset; transcript kept, party dir left in place ($expected_dir/log); re-run close after fixing." >&2
|
echo "party close: HOME is unset; transcript kept, party dir left in place ($expected_dir/log); re-run close after fixing." >&2
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
_cl_prev=-1
|
|
||||||
for _cl_i in 1 2 3; do
|
|
||||||
_cl_size=$(wc -c < "$expected_dir/log")
|
|
||||||
[ "$_cl_size" -eq "$_cl_prev" ] && break
|
|
||||||
_cl_prev="$_cl_size"
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
_cl_dest="$HOME/party-$name-$(date -u '+%Y%m%d-%H%M%S').log"
|
|
||||||
if mv "$expected_dir/log" "$_cl_dest" 2>/dev/null; then
|
|
||||||
echo "party close: transcript saved to $_cl_dest"
|
|
||||||
else
|
else
|
||||||
echo "party close: could not save transcript; party dir left in place ($expected_dir/log); re-run close after fixing." >&2
|
echo "party close: could not save transcript; party dir left in place ($expected_dir/log); re-run close after fixing." >&2
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf "$expected_dir"
|
rm -rf "$expected_dir"
|
||||||
|
|
@ -1029,20 +1046,18 @@ EOF
|
||||||
# already confirmed dead by the liveness check above, so unlike
|
# already confirmed dead by the liveness check above, so unlike
|
||||||
# close there's no pipe-pane `cat` still draining and no
|
# close there's no pipe-pane `cat` still draining and no
|
||||||
# quiescence poll is needed before moving it.
|
# quiescence poll is needed before moving it.
|
||||||
if [ -s "$d/log" ]; then
|
_cn_name=${d##*"party-$USER:"}
|
||||||
if [ -z "$HOME" ]; then
|
_cn_name=${_cn_name%.d}
|
||||||
|
if rescue_transcript "$d" "$_cn_name" 0; then
|
||||||
|
[ -z "$_rt_dest" ] || echo "party clean: transcript saved to $_rt_dest"
|
||||||
|
else
|
||||||
|
_rt_rc=$?
|
||||||
|
if [ "$_rt_rc" -eq 2 ]; then
|
||||||
echo "party clean: skipping $d (HOME is unset; leaving transcript)" >&2
|
echo "party clean: skipping $d (HOME is unset; leaving transcript)" >&2
|
||||||
continue
|
|
||||||
fi
|
|
||||||
_cn_name=${d##*"party-$USER:"}
|
|
||||||
_cn_name=${_cn_name%.d}
|
|
||||||
_cn_dest="$HOME/party-$_cn_name-$(date -u '+%Y%m%d-%H%M%S').log"
|
|
||||||
if mv "$d/log" "$_cn_dest" 2>/dev/null; then
|
|
||||||
echo "party clean: transcript saved to $_cn_dest"
|
|
||||||
else
|
else
|
||||||
echo "party clean: skipping $d (could not save transcript)" >&2
|
echo "party clean: skipping $d (could not save transcript)" >&2
|
||||||
continue
|
|
||||||
fi
|
fi
|
||||||
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf "$d"
|
rm -rf "$d"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue