From d07abfb2e5ac828fce252a7f03a737d3f78893f8 Mon Sep 17 00:00:00 2001 From: Matt Spinola Date: Fri, 25 Sep 2026 14:06:57 -0400 Subject: [PATCH] run-series.cmd: sync on a partial build, stop only on a total failure The wrapper stopped on any non-zero code from the build. On 2026-09-25 that cost five sessions on both replicas: TradingView restated two put/call closes, the build refused those two by design, and the wrapper exited before its syncs while thirteen breadth series sat correct on the producer. It now reads the build's new exit codes (marketdata EXIT_PARTIAL): sync on 0 and on 2, stop only on 1. The refusal stays visible, because the wrapper exits with the build's code rather than the push's, so a partial run still reports 2. Testing a specific code needs equality, not `if errorlevel`, which is true for that code or any larger one and would read 2 as 1. Two chained `if not` string compares are the cmd idiom and avoid a numeric parse on an empty ERRORLEVEL. The live copy on the box has to be updated by hand; this is the example it is deployed from. Co-Authored-By: Claude Opus 5 --- docs/examples/windows/run-series.cmd | 36 ++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/docs/examples/windows/run-series.cmd b/docs/examples/windows/run-series.cmd index d5a4a01..adde5fd 100644 --- a/docs/examples/windows/run-series.cmd +++ b/docs/examples/windows/run-series.cmd @@ -44,7 +44,27 @@ REM calling the same two sync scripts, and two mirror passes running REM concurrently against the same replicas is a race nobody wants to debug, so REM the series routines stay out of the futures window entirely. REM -REM `if errorlevel 1` tests >= 1 and needs no expansion, so it is safe here. +REM EXIT CODES, AND WHY A REFUSAL NO LONGER STOPS THE SYNC +REM ------------------------------------------------------------------------ +REM 0 nothing refused. +REM 2 PARTIAL: some symbols refused, the rest are in the store and correct. +REM 1 nothing usable came of the run: every symbol refused, or a hard error. +REM +REM This wrapper syncs on 0 and on 2, and stops only on 1. It used to stop on any +REM non-zero code, and on 2026-09-25 that cost a week of data: TradingView restated +REM two put/call closes, the build refused those two symbols exactly as designed, +REM and the wrapper exited before its syncs -- so thirteen breadth series sat +REM correct on this box and five sessions stale on both replicas until a human +REM noticed. A refusal has to stop the SYMBOL, not the delivery of every other one. +REM The refusal is still visible: the wrapper exits 2, which is non-zero, and the +REM build has already printed the refused symbol and the reason. +REM +REM Testing a specific code needs equality, not `if errorlevel`, which is true for +REM N or any larger code, and so would treat 2 as 1. Two chained `if not` tests +REM are the cmd idiom, and a string compare avoids any numeric parsing surprise +REM on an empty ERRORLEVEL. +REM +REM `if errorlevel 1` tests >= 1 and needs no expansion, so it is safe below. REM `|| exit /b %ERRORLEVEL%` would NOT be: cmd expands %ERRORLEVEL% when it parses REM the line, which is BEFORE the command on that line has run, so it would return REM the previous command's code. On its own line, after the command, it is correct. @@ -56,7 +76,8 @@ REM Unscoped: every registry series symbol. A symbol with no raw files is a REM refusal, not a skip, because the routine pulls every one of them every night REM and a missing one means it did not. "%MDEXE%" --build-tradingview -if errorlevel 1 exit /b %ERRORLEVEL% +set "RC=%ERRORLEVEL%" +if not "%RC%"=="0" if not "%RC%"=="2" exit /b %RC% REM --------------------------------------------------------------------------- REM Chained replica syncs, same discipline and same order as run-prices.cmd: the @@ -64,7 +85,9 @@ REM Mac sync first, the VPS push second, so the Mac replica is current even on a REM day the VPS is unreachable. Both scripts mirror BOTH stores, so the COT and REM futures passes here are cheap no-op re-scans. Reached on an "already current" REM build too (exit 0, nothing written): a no-op mirror is cheap, and skipping it -REM would need the wrapper to tell the two exit-0 cases apart. +REM would need the wrapper to tell the two exit-0 cases apart. Reached on a PARTIAL +REM build as well (exit 2), which is the whole point of the code: the store is a +REM valid state whatever refused, so mirroring it can only make a replica fresher. REM REM The raw JSON under _raw\tradingview never rides along: both scripts exclude REM _raw by name at any depth, for databento's paid raw store. Keep the directory @@ -73,4 +96,9 @@ call "REPLACE_WITH_SCHEDULER_DIR\sync-store.cmd" if errorlevel 1 exit /b %ERRORLEVEL% call "REPLACE_WITH_SCHEDULER_DIR\push-to-server.cmd" -exit /b %ERRORLEVEL% +if errorlevel 1 exit /b %ERRORLEVEL% + +REM The build's code, not the push's: a partial build that synced cleanly is still +REM a run with a refusal in it, and the operator and the verifier both want to see +REM that rather than a 0. +exit /b %RC%