mirror of
https://github.com/rclone/rclone.git
synced 2025-12-06 00:03:32 +00:00
Before this fix there were various issues with the test server framework, most noticeably servers stopping when they shouldn't causing timeouts. This was caused by the reference counting in the Go code not being engineered to work in multiple processes so it was not working at all properly. This fix moves the reference counting logic to the start scripts and in turn removes that logic from the Go code. This means that the reference counting is now global and works correctly over multiple processes.
102 lines
2.0 KiB
Bash
102 lines
2.0 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
BASE="${STATE_DIR:-${XDG_RUNTIME_DIR:-/tmp}/rclone-test-server}"
|
||
NAME="$(basename "$0")"
|
||
ROOT="${BASE}/${NAME}"
|
||
STATE="${ROOT}/state"
|
||
LOCKF="${ROOT}/lock"
|
||
REFC="${STATE}/refcount"
|
||
ENVF="${STATE}/env"
|
||
|
||
mkdir -p "${STATE}"
|
||
[[ -f "${REFC}" ]] || echo 0 >"${REFC}"
|
||
[[ -f "${ENVF}" ]] || : >"${ENVF}"
|
||
: > "${LOCKF}" # ensure file exists
|
||
|
||
# status helper that won't trip set -e
|
||
_is_running() { set +e; status >/dev/null 2>&1; local rc=$?; set -e; return $rc; }
|
||
|
||
_acquire_lock() {
|
||
# open fd 9 on lock file and take exclusive lock
|
||
exec 9>"${LOCKF}"
|
||
flock -x 9
|
||
}
|
||
|
||
_release_lock() {
|
||
flock -u 9
|
||
exec 9>&-
|
||
}
|
||
|
||
case "${1:-}" in
|
||
start)
|
||
_acquire_lock
|
||
trap '_release_lock' EXIT
|
||
|
||
rc=$(cat "${REFC}" 2>/dev/null || echo 0)
|
||
|
||
if (( rc == 0 )); then
|
||
# First client: ensure a clean instance, then start and cache env
|
||
if _is_running; then
|
||
stop || true
|
||
fi
|
||
if ! out="$(start)"; then
|
||
echo "failed to start" >&2
|
||
exit 1
|
||
fi
|
||
printf "%s\n" "$out" > "${ENVF}"
|
||
else
|
||
# Already owned: make sure it’s still up; if not, restart and refresh env
|
||
if ! _is_running; then
|
||
if ! out="$(start)"; then
|
||
echo "failed to restart" >&2
|
||
exit 1
|
||
fi
|
||
printf "%s\n" "$out" > "${ENVF}"
|
||
fi
|
||
fi
|
||
|
||
rc=$((rc+1)); echo "${rc}" > "${REFC}"
|
||
cat "${ENVF}"
|
||
|
||
trap - EXIT
|
||
_release_lock
|
||
;;
|
||
|
||
stop)
|
||
_acquire_lock
|
||
trap '_release_lock' EXIT
|
||
|
||
rc=$(cat "${REFC}" 2>/dev/null || echo 0)
|
||
if (( rc > 0 )); then rc=$((rc-1)); fi
|
||
echo "${rc}" > "${REFC}"
|
||
if (( rc == 0 )) && _is_running; then
|
||
stop || true
|
||
fi
|
||
|
||
trap - EXIT
|
||
_release_lock
|
||
;;
|
||
|
||
reset)
|
||
_acquire_lock
|
||
trap '_release_lock' EXIT
|
||
|
||
stop || true
|
||
rm -rf "${BASE}"
|
||
|
||
trap - EXIT
|
||
_release_lock
|
||
;;
|
||
|
||
status)
|
||
# passthrough; do NOT take the lock
|
||
status
|
||
;;
|
||
|
||
*)
|
||
echo "usage: $0 {start|stop|reset|status}" >&2
|
||
exit 2
|
||
;;
|
||
esac
|