mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-13 15:23:44 +00:00
Stabilize hot-dev watcher restarts
This commit is contained in:
parent
e87c2629ea
commit
3f6c910f3a
3 changed files with 52 additions and 5 deletions
|
|
@ -153,6 +153,13 @@ to be listening.
|
|||
Changes to `scripts/hot-dev.sh` and `scripts/hot-dev-bg.sh` must therefore
|
||||
stay on their own direct dev-runtime orchestration proof path instead of
|
||||
piggybacking on installer proof coverage for unrelated deployment scripts.
|
||||
That same dev-runtime orchestration boundary also owns watcher stability for
|
||||
the managed local stack: `scripts/hot-dev.sh` may only rebuild the backend for
|
||||
runtime Go sources, not `*_test.go` churn, and it must suppress `pulse` binary
|
||||
change events produced by its own successful managed rebuilds or startup build.
|
||||
Otherwise unrelated parallel test edits or hot-dev's own binary output can
|
||||
tear down `7655`, produce transient `5173` proxy failures, and undermine the
|
||||
canonical browser-runtime proof path.
|
||||
That same launcher boundary also owns its CLI contract: managed commands such
|
||||
as `start --takeover` and `restart --takeover` must preserve the takeover flag
|
||||
through the actual script entrypoint instead of silently dropping second-arg
|
||||
|
|
|
|||
|
|
@ -514,8 +514,9 @@ log_info "Starting backend file watcher..."
|
|||
(
|
||||
cd "${ROOT_DIR}"
|
||||
|
||||
LAST_RESTART_TIME=0
|
||||
WATCHER_READY_AT=$(date +%s)
|
||||
LAST_RESTART_TIME=0
|
||||
SELF_BUILD_IGNORE_UNTIL=$((WATCHER_READY_AT + HOT_DEV_WATCHER_STARTUP_GRACE_SECONDS + 5))
|
||||
|
||||
watcher_within_startup_grace() {
|
||||
local now
|
||||
|
|
@ -523,6 +524,27 @@ log_info "Starting backend file watcher..."
|
|||
(( now - WATCHER_READY_AT < HOT_DEV_WATCHER_STARTUP_GRACE_SECONDS ))
|
||||
}
|
||||
|
||||
mark_self_build_output() {
|
||||
local now
|
||||
now=$(date +%s)
|
||||
SELF_BUILD_IGNORE_UNTIL=$((now + 5))
|
||||
}
|
||||
|
||||
manual_build_event_suppressed() {
|
||||
local now
|
||||
now=$(date +%s)
|
||||
(( now < SELF_BUILD_IGNORE_UNTIL ))
|
||||
}
|
||||
|
||||
should_rebuild_backend_for_change() {
|
||||
local changed_file=$1
|
||||
|
||||
[[ "${changed_file}" == *.go ]] || return 1
|
||||
[[ "${changed_file}" == *_test.go ]] && return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
restart_backend() {
|
||||
# Debounce: skip if we restarted less than 3 seconds ago
|
||||
local now
|
||||
|
|
@ -604,6 +626,7 @@ log_info "Starting backend file watcher..."
|
|||
|
||||
# Use the same build logic as the initial build.
|
||||
if build_backend_binary; then
|
||||
mark_self_build_output
|
||||
restart_backend
|
||||
else
|
||||
log_error "✗ Build failed; keeping the current backend process running."
|
||||
|
|
@ -627,9 +650,12 @@ log_info "Starting backend file watcher..."
|
|||
log_info "🚀 Managed restart requested, restarting backend..."
|
||||
restart_backend
|
||||
elif [[ "$changed_file" == "${ROOT_DIR}/pulse" ]]; then
|
||||
if manual_build_event_suppressed; then
|
||||
continue
|
||||
fi
|
||||
log_info "🚀 Manual build detected (pulse binary changed), restarting..."
|
||||
restart_backend
|
||||
elif [[ "$changed_file" == *.go ]] || [[ "$event" =~ CREATE|DELETE|MOVED|ATTRIB ]]; then
|
||||
elif should_rebuild_backend_for_change "$changed_file"; then
|
||||
rebuild_backend "$changed_file"
|
||||
fi
|
||||
done
|
||||
|
|
@ -651,6 +677,9 @@ log_info "Starting backend file watcher..."
|
|||
if [[ "$changed_file" == "${HOT_DEV_RESTART_SENTINEL}" ]]; then
|
||||
log_info "🚀 Managed restart requested, restarting backend..."
|
||||
else
|
||||
if manual_build_event_suppressed; then
|
||||
continue
|
||||
fi
|
||||
log_info "🚀 Manual build detected (pulse binary changed), restarting..."
|
||||
fi
|
||||
restart_backend
|
||||
|
|
@ -663,8 +692,7 @@ log_info "Starting backend file watcher..."
|
|||
--include '\.go$' \
|
||||
"${ROOT_DIR}/cmd" "${ROOT_DIR}/internal" "${ROOT_DIR}/pkg" 2>/dev/null | \
|
||||
while read -r changed_file; do
|
||||
# fswatch sends absolute paths, simple check for .go extension
|
||||
if [[ "$changed_file" == *.go ]]; then
|
||||
if should_rebuild_backend_for_change "$changed_file"; then
|
||||
rebuild_backend "$changed_file"
|
||||
fi
|
||||
done
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ set -euo pipefail
|
|||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
HOT_DEV_BG="${ROOT_DIR}/scripts/hot-dev-bg.sh"
|
||||
HOT_DEV="${ROOT_DIR}/scripts/hot-dev.sh"
|
||||
CLEAN_MOCK_ALERTS="${ROOT_DIR}/scripts/clean-mock-alerts.sh"
|
||||
DEV_CHECK="${ROOT_DIR}/scripts/dev-check.sh"
|
||||
PACKAGE_JSON="${ROOT_DIR}/package.json"
|
||||
|
|
@ -468,7 +469,7 @@ test_makefile_routes_managed_runtime_through_npm() {
|
|||
|
||||
test_hot_dev_script_advertises_foreground_escape_hatch() {
|
||||
local output
|
||||
output="$(sed -n '1,30p' "${ROOT_DIR}/scripts/hot-dev.sh")"
|
||||
output="$(sed -n '1,30p' "${HOT_DEV}")"
|
||||
|
||||
assert_contains "hot-dev header identifies foreground escape hatch" "${output}" "hot-dev.sh - Foreground Pulse dev runtime escape hatch"
|
||||
assert_contains "hot-dev usage points to managed runtime first" "${output}" "npm run dev # Canonical managed dev runtime"
|
||||
|
|
@ -476,6 +477,16 @@ test_hot_dev_script_advertises_foreground_escape_hatch() {
|
|||
assert_not_contains "hot-dev usage no longer claims standard dev mode" "${output}" "Standard dev mode"
|
||||
}
|
||||
|
||||
test_hot_dev_script_ignores_test_only_backend_churn() {
|
||||
local output
|
||||
output="$(cat "${HOT_DEV}")"
|
||||
|
||||
assert_contains "hot-dev watcher ignores Go test files" "${output}" '[[ "${changed_file}" == *_test.go ]] && return 1'
|
||||
assert_contains "hot-dev watcher routes rebuild decisions through shared helper" "${output}" 'should_rebuild_backend_for_change "$changed_file"'
|
||||
assert_contains "hot-dev watcher suppresses self-build binary restart loops" "${output}" 'if manual_build_event_suppressed; then'
|
||||
assert_contains "hot-dev watcher suppresses startup self-build pulse events" "${output}" 'SELF_BUILD_IGNORE_UNTIL=$((WATCHER_READY_AT + HOT_DEV_WATCHER_STARTUP_GRACE_SECONDS + 5))'
|
||||
}
|
||||
|
||||
test_hot_dev_bg_script_advertises_managed_entrypoint() {
|
||||
local output
|
||||
output="$(cat "${ROOT_DIR}/scripts/hot-dev-bg.sh")"
|
||||
|
|
@ -744,6 +755,7 @@ main() {
|
|||
test_frontend_package_exposes_managed_runtime_entrypoints
|
||||
test_makefile_routes_managed_runtime_through_npm
|
||||
test_hot_dev_script_advertises_foreground_escape_hatch
|
||||
test_hot_dev_script_ignores_test_only_backend_churn
|
||||
test_hot_dev_bg_script_advertises_managed_entrypoint
|
||||
test_hot_dev_bg_usage_prefers_managed_wrappers
|
||||
test_integration_readme_uses_managed_backend_restart_wrapper
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue