From 1331e4dc95e46922cb3c56a2880ac2b4833d3898 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 22 Mar 2024 10:43:39 -0300 Subject: [PATCH] fix: Watch command should not spawn more than one tsc watch The watch command was spawning multiple tsc watch processes, which conflicted with each other. This could happen if a generate was kicked off while another one was running, which is now prevented via a lockfile; if a generate tries to run while the lock is set, it just sleeps for a few seconds and retries later. The other issue is that the tsc watch was not getting killed by the `stop_tsc_watch` function. It seems that yarn starts whatever command it receives as a detached process, so killing the parent still left a zombie tsc watch running. By calling tsc directly we now start the process ourselves and get the proper pid to kill it later. --- yarn-project/watch.sh | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/yarn-project/watch.sh b/yarn-project/watch.sh index 250de4e6d7d..10338447ffa 100755 --- a/yarn-project/watch.sh +++ b/yarn-project/watch.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -eu +set -u DEBOUNCE_DURATION=3 # Set a high duration for debounce since nargo build may pause for a long time during a compilation INOTIFY_EVENTS="modify,create,delete,move" @@ -23,33 +23,52 @@ debounce() { # Start typescript watch process in the background and store process ID in a file start_tsc_watch() { - yarn tsc -b tsconfig.json --watch & + local tsc_bin=$(yarn bin tsc) + $tsc_bin -b tsconfig.json --watch & TSC_PID=$! echo "$TSC_PID" > .tsc.pid } # Stops the typescript watch process stop_tsc_watch() { - local tsc_pid=$(cat ".tsc.pid"); - kill $tsc_pid || true + if [ -f .tsc.pid ]; then + echo "Stopping tsc watch..." + local tsc_pid=$(cat ".tsc.pid"); + echo KILLING $tsc_pid + kill $tsc_pid + fi } # Kill typescript, run a yarn generate, and restart typescript run_generate() { - echo "Change detected at $1" + # If already generating something, then try again in a few seconds + if [ -f .generating.lock ]; then + debounce run_generate $1 + return + fi + # Pause ts watch to generate code and acquire a lock + echo "LOCKED" > .generating.lock + echo "Change detected at $1..." stop_tsc_watch - FORCE_COLOR=true yarn workspaces foreach --parallel --topological-dev --verbose run generate:$1 - echo "Generate complete, restarting typescript..." + if FORCE_COLOR=true yarn workspaces foreach --parallel --topological-dev --verbose run generate:$1; then + echo "Generate complete, restarting tsc watch..." + else + echo "Generate failed, restarting tsc watch..." + fi + # Restart tsc watch and release lock sleep 3 start_tsc_watch + rm .generating.lock } # Remove all temp files with process or run ids on exit cleanup() { - rm .tsc.pid || true - rm .debounce-* || true + rm -f .tsc.pid || true + rm -f .debounce-* || true + rm -f .generating.lock || true } trap cleanup EXIT +cleanup # Start tsc watch in background start_tsc_watch @@ -68,7 +87,7 @@ while true; do debounce run_generate "l1-contracts" ;; *) - echo "Change at $folder not matched with any project" + echo "Error: change at $folder not matched with any project" exit 1 ;; esac