keep CLI units current during rebuilds

This commit is contained in:
udo 2026-07-13 14:20:29 +00:00
parent 97ecc6edd6
commit cd2fa163e6
4 changed files with 19 additions and 7 deletions

View File

@ -358,8 +358,9 @@ header free-functions are `inline`. The wasm backend exposes only declarations
cold component that exceeds the development epoch window and proves the
parent request still renders it. The dependency-invalidation gate also holds
parent and child compile locks across a transitive source edit, proves a
warmed request returns the last atomically published result without waiting,
and then proves the new dependency result appears after rebuild completion.
warmed HTTP request returns the last atomically published result without
waiting, while a CLI request waits and returns only the current dependency
result after rebuild completion.
- **WebSocket end-to-end**: a headless client performs a raw WS handshake to
`:HTTP_PORT` with path `/site/tests/websockets.ws.uce` (self-resolving

View File

@ -84,14 +84,24 @@ rebuild_lock_pid=$!
sleep 0.2
sed -i 's/dependency-marker-b/dependency-marker-d/' "$source_dir/child.uce"
started_at=$(date +%s%N)
assert_marker parent dependency-marker-b
http_during_lock=$(http_marker)
elapsed_ms=$(( ($(date +%s%N) - started_at) / 1000000 ))
if [[ "$http_during_lock" != *"dependency-marker-b"* ]]; then
echo "HTTP request did not serve the last complete artifact during rebuild: $http_during_lock" >&2
exit 1
fi
if (( elapsed_ms >= 2000 )); then
echo "request waited ${elapsed_ms}ms for an active transitive rebuild" >&2
echo "HTTP request waited ${elapsed_ms}ms for an active transitive rebuild" >&2
exit 1
fi
started_at=$(date +%s%N)
assert_marker parent dependency-marker-d
elapsed_ms=$(( ($(date +%s%N) - started_at) / 1000000 ))
if (( elapsed_ms < 2000 )); then
echo "CLI request returned before the locked rebuild published the current artifact (${elapsed_ms}ms)" >&2
exit 1
fi
wait "$rebuild_lock_pid"
assert_marker parent dependency-marker-d
# Warm every configured worker, then replace the artifact while retaining its
# whole-second mtime. The worker cache must notice the nanosecond/ctime change.

View File

@ -850,7 +850,8 @@ SharedUnit* compiler_get_shared_unit_internal(Request* context, String file_name
SharedUnit* su = new SharedUnit();
setup_unit_paths(context, su, file_name);
int fdlock = compiler_open_lock_file(su->wasm_name + ".lock", "shared-unit:" + file_name, !force_recompile);
bool can_serve_stale = !force_recompile && compiler_request_can_serve_stale_artifact(context);
int fdlock = compiler_open_lock_file(su->wasm_name + ".lock", "shared-unit:" + file_name, can_serve_stale);
if(fdlock == -2 && file_exists(su->wasm_name))
{
auto state = inspect_shared_unit_filesystem(context, su);

View File

@ -100,7 +100,7 @@ static bool wasm_artifact_exists(Request* context, const String& entry_unit)
// metadata mismatches, which can leave stale wasm with old imports.
bool source_missing = false;
if(compiler_unit_needs_recompile(context, entry_unit, &source_missing))
return(compiler_request_can_serve_stale_artifact(context) || compiler_unit_compile_in_progress(context, entry_unit));
return(compiler_request_can_serve_stale_artifact(context));
if(source_missing)
return(false);
return(true);