keep web requests off rebuild path

This commit is contained in:
udo
2026-07-13 12:25:42 +00:00
parent 5195ebeb25
commit 97ecc6edd6
6 changed files with 37 additions and 8 deletions
+7 -6
View File
@@ -138,12 +138,13 @@ following allocator/relocation call even though no guest loop consumed it.
The proactive compiler and request workers coordinate through a per-unit file The proactive compiler and request workers coordinate through a per-unit file
lock. Unit compilation writes and validates a process-unique temporary wasm lock. Unit compilation writes and validates a process-unique temporary wasm
file, then publishes it with an atomic rename. While another process holds the file, then publishes it with an atomic rename. When proactive compilation is
lock for a stale unit, a request may therefore keep using the last complete enabled, HTTP and WebSocket requests keep using the last complete artifact
artifact instead of waiting across a transitive rebuild. Once the lock is while stale units rebuild in the background; CLI and explicit compile paths
released, normal freshness checks require the new artifact; a failed rebuild remain synchronous. A failed rebuild removes availability and surfaces the
removes availability and surfaces the compiler error rather than serving the compiler error rather than serving the old unit indefinitely. The per-unit lock
old unit indefinitely. also keeps concurrent synchronous compilers from waiting across a transitive
graph when a last complete artifact is available.
--- ---
+20
View File
@@ -11,6 +11,7 @@ if [[ -z "$bin_directory" && -r /etc/uce/settings.cfg ]]; then
fi fi
bin_directory="${bin_directory:-/tmp/uce/work}" bin_directory="${bin_directory:-/tmp/uce/work}"
cache_dir="" cache_dir=""
http_host="${UCE_TEST_HTTP_HOST:-uce.openfu.com}"
cleanup() { cleanup() {
rm -rf "$source_dir" rm -rf "$source_dir"
@@ -43,9 +44,28 @@ assert_marker() {
fi fi
} }
http_marker() {
curl -fsS -H "Host: $http_host" "http://127.0.0.1/$test_name/parent.uce"
}
assert_marker parent dependency-marker-a assert_marker parent dependency-marker-a
if [[ "$(http_marker)" != *"dependency-marker-a"* ]]; then
echo "HTTP warm-up did not return dependency-marker-a" >&2
exit 1
fi
sed -i 's/dependency-marker-a/dependency-marker-b/' "$source_dir/child.uce" sed -i 's/dependency-marker-a/dependency-marker-b/' "$source_dir/child.uce"
started_at=$(date +%s%N)
http_during_rebuild=$(http_marker)
elapsed_ms=$(( ($(date +%s%N) - started_at) / 1000000 ))
if [[ "$http_during_rebuild" != *"dependency-marker-a"* && "$http_during_rebuild" != *"dependency-marker-b"* ]]; then
echo "HTTP rebuild request returned neither complete artifact: $http_during_rebuild" >&2
exit 1
fi
if (( elapsed_ms >= 2000 )); then
echo "HTTP request spent ${elapsed_ms}ms rebuilding a stale artifact" >&2
exit 1
fi
assert_marker parent dependency-marker-b assert_marker parent dependency-marker-b
# A proactive rebuild owns these same per-unit locks. While it publishes fresh # A proactive rebuild owns these same per-unit locks. While it publishes fresh
+7
View File
@@ -975,6 +975,13 @@ bool compiler_unit_compile_in_progress(Request* context, String file_name)
return(false); return(false);
} }
bool compiler_request_can_serve_stale_artifact(Request* context)
{
return(context && context->server && !context->resources.is_cli &&
to_bool(context->server->config["PROACTIVE_COMPILE_ENABLED"], true) &&
float_val(context->server->config["PROACTIVE_COMPILE_CHECK_INTERVAL"]) > 0);
}
void unit_render(String file_name) void unit_render(String file_name)
{ {
unit_render(file_name, *context); unit_render(file_name, *context);
+1
View File
@@ -18,6 +18,7 @@ SharedUnit* get_shared_unit(Request* context, String file_name);
String compiler_error_page_unit(Request* context, String config_key); String compiler_error_page_unit(Request* context, String config_key);
bool compiler_unit_compile_pending(Request* context, String file_name); bool compiler_unit_compile_pending(Request* context, String file_name);
bool compiler_unit_compile_in_progress(Request* context, String file_name); bool compiler_unit_compile_in_progress(Request* context, String file_name);
bool compiler_request_can_serve_stale_artifact(Request* context);
String compiler_site_directory(Request* context); String compiler_site_directory(Request* context);
StringList compiler_scan_site_units(Request* context); StringList compiler_scan_site_units(Request* context);
StringList compiler_list_known_units(Request* context); StringList compiler_list_known_units(Request* context);
+1 -1
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. // metadata mismatches, which can leave stale wasm with old imports.
bool source_missing = false; bool source_missing = false;
if(compiler_unit_needs_recompile(context, entry_unit, &source_missing)) if(compiler_unit_needs_recompile(context, entry_unit, &source_missing))
return(compiler_unit_compile_in_progress(context, entry_unit)); return(compiler_request_can_serve_stale_artifact(context) || compiler_unit_compile_in_progress(context, entry_unit));
if(source_missing) if(source_missing)
return(false); return(false);
return(true); return(true);
+1 -1
View File
@@ -1606,7 +1606,7 @@ private:
return(1); return(1);
} }
if(!file_exists_host(worker.unit_wasm_path(resolved)) || (compiler_unit_needs_recompile(context, resolved, 0) && !compiler_unit_compile_in_progress(context, resolved))) if(!file_exists_host(worker.unit_wasm_path(resolved)) || (compiler_unit_needs_recompile(context, resolved, 0) && !compiler_request_can_serve_stale_artifact(context) && !compiler_unit_compile_in_progress(context, resolved)))
get_shared_unit(context, resolved); get_shared_unit(context, resolved);
size_t unit_index = 0; size_t unit_index = 0;