Ensure nested CLI components are fresh
This commit is contained in:
parent
dafffb4ab6
commit
ee022f0398
@ -146,9 +146,10 @@ a stale entry artifact: they return `503 Service Unavailable` with
|
||||
`Retry-After: 1`, allowing the client to retry after the priority rebuild.
|
||||
CLI and explicit compile paths remain synchronous. A failed rebuild removes
|
||||
availability and surfaces the compiler error rather than serving the old unit
|
||||
indefinitely. The per-unit lock also keeps concurrent synchronous compilers
|
||||
from waiting across a transitive graph when a last complete artifact is
|
||||
available.
|
||||
indefinitely. This freshness contract includes components resolved lazily from
|
||||
an otherwise-current CLI entry unit: if the proactive compiler already owns a
|
||||
stale child's lock, the CLI request joins that compile and waits for the fresh
|
||||
artifact. Read-only HTTP may use the child's last complete artifact instead.
|
||||
|
||||
Before preprocessing, the compiler verifies that the worker can actually read
|
||||
the source. An unreadable path is reported as a source-read failure with a
|
||||
|
||||
@ -21,6 +21,7 @@ mutation_file="/tmp/uce-dependency-mutation-$$"
|
||||
post_body="/tmp/uce-dependency-post-body-$$"
|
||||
post_headers="/tmp/uce-dependency-post-headers-$$"
|
||||
lock_ready_file="/tmp/uce-dependency-lock-ready-$$"
|
||||
nested_lock_ready_file="/tmp/uce-nested-lock-ready-$$"
|
||||
race_output="/tmp/uce-source-race-output-$$"
|
||||
race_error="/tmp/uce-source-race-error-$$"
|
||||
race_status="/tmp/uce-source-race-status-$$"
|
||||
@ -31,7 +32,7 @@ cleanup() {
|
||||
if [[ -n "$cache_dir" ]]; then
|
||||
rm -rf "$cache_dir"
|
||||
fi
|
||||
rm -f "$mutation_file" "$post_body" "$post_headers" "$lock_ready_file" "$race_output" "$race_error" "$race_status"
|
||||
rm -f "$mutation_file" "$post_body" "$post_headers" "$lock_ready_file" "$nested_lock_ready_file" "$race_output" "$race_error" "$race_status"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
mkdir -p "$source_dir"
|
||||
@ -175,6 +176,47 @@ if (( elapsed_ms < 2000 )); then
|
||||
fi
|
||||
wait "$rebuild_lock_pid"
|
||||
|
||||
# CLI freshness applies to every nested component, not only the request entry
|
||||
# unit. Hold the changed child's compile lock as a proactive rebuild would: the
|
||||
# parent CLI request must wait and render the new child, never its stale wasm.
|
||||
printf '%s\n' 'COMPONENT(Request& context) { print("nested-component-marker-a"); }' >"$source_dir/nested-child.uce"
|
||||
printf '%s\n' \
|
||||
'CLI(Request& context) { DValue props; print(component("nested-child", props, context)); }' >"$source_dir/nested-parent.uce"
|
||||
assert_marker nested-parent nested-component-marker-a
|
||||
nested_child_wasm="$cache_dir/nested-child.uce.wasm"
|
||||
(
|
||||
exec 8>"$nested_child_wasm.lock"
|
||||
flock 8
|
||||
: >"$nested_lock_ready_file"
|
||||
sleep 3
|
||||
) &
|
||||
nested_lock_pid=$!
|
||||
deadline=$((SECONDS + 5))
|
||||
while [[ ! -e "$nested_lock_ready_file" && $SECONDS -lt $deadline ]]; do
|
||||
if ! kill -0 "$nested_lock_pid" 2>/dev/null; then
|
||||
echo "nested component lock exited before acquisition" >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 0.05
|
||||
done
|
||||
if [[ ! -e "$nested_lock_ready_file" ]]; then
|
||||
echo "nested component lock was not acquired before deadline" >&2
|
||||
exit 1
|
||||
fi
|
||||
sed -i 's/nested-component-marker-a/nested-component-marker-b/' "$source_dir/nested-child.uce"
|
||||
started_at=$(date +%s%N)
|
||||
nested_output=$(scripts/uce-cli "/$test_name/nested-parent.uce")
|
||||
elapsed_ms=$(( ($(date +%s%N) - started_at) / 1000000 ))
|
||||
wait "$nested_lock_pid"
|
||||
if [[ "$nested_output" != *"nested-component-marker-b"* ]]; then
|
||||
echo "CLI nested component returned stale wasm: $nested_output" >&2
|
||||
exit 1
|
||||
fi
|
||||
if (( elapsed_ms < 2000 )); then
|
||||
echo "CLI nested component did not wait for the active rebuild (${elapsed_ms}ms)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Warm every configured worker, then replace the artifact while retaining its
|
||||
# whole-second mtime. The worker cache must notice the nanosecond/ctime change.
|
||||
for _ in {1..16}; do assert_marker parent dependency-marker-d; done
|
||||
|
||||
@ -1612,9 +1612,10 @@ private:
|
||||
}
|
||||
|
||||
bool stale = compiler_unit_needs_recompile(context, resolved, 0);
|
||||
if(stale && compiler_request_can_serve_stale_artifact(context))
|
||||
bool can_serve_stale = compiler_request_can_serve_stale_artifact(context);
|
||||
if(stale && can_serve_stale)
|
||||
compiler_prioritize_unit(context, resolved);
|
||||
if(!file_exists_host(worker.unit_wasm_path(resolved)) || (stale && !compiler_request_can_serve_stale_artifact(context) && !compiler_unit_compile_in_progress(context, resolved)))
|
||||
if(!file_exists_host(worker.unit_wasm_path(resolved)) || (stale && !can_serve_stale))
|
||||
get_shared_unit(context, resolved);
|
||||
|
||||
size_t unit_index = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user