feat(scripting): self-contained script worker publish, docker-dev drill, §8 perf harness (lmxopcua#780 P1)
v2-ci / unit-tests (push) Waiting to run
v2-ci / unit-tests (push) Waiting to run
- A self-contained Host publish (-r win-x64 --self-contained, the Windows installs) now publishes the ScriptWorker self-contained for the same RID into script-worker/. The launcher starts its apphost directly when runtimeconfig.json lists includedFrameworks. A framework-dependent worker (docker-dev) keeps running through the dotnet muxer. - docker-dev/docker-compose.script-runner.yml: OutOfProcess for the central pair's VT + Calc seams. Live drill recorded in design §12.1 (runaway kill + quarantine, kill -9 recovery, open circuit with /health/ready still 200, metrics). - ScriptRunnerPerfTests (Category=Perf, opt-in via OTOPCUA_SCRIPT_PERF=1): InProcess vs OutOfProcess at K=1/2/4. The accepted 5k evals/s/node gate passes on macOS and windev. The host-CPU, RSS and Windows latency budget misses are tracked as #789. - Fix: the single-flight slot is released before the awaiting caller resumes. Before, a caller that started its next run right after the previous one returned could be refused with "previous evaluation still running", which the seams publish as Bad. - Fix: the worker compiles on dedicated threads, not the thread pool. A burst of cold loads starved the heartbeat, and the host killed the shard (found on windev). Load-timeout queueing is #790. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -35,6 +35,16 @@ internal static class Scripts
|
||||
IReadOnlyDictionary<string, DataValueSnapshot>? inputs = null, ILogger? logger = null)
|
||||
=> new(key, ScriptContextKind.VirtualTag, source, inputs ?? NoInputs, timeout ?? TimeSpan.FromSeconds(5), logger);
|
||||
|
||||
/// <summary>
|
||||
/// Name of the environment variable that points the suite at a different worker entry than the one built beside
|
||||
/// the tests — e.g. the apphost of a self-contained <c>script-worker/</c> from a <c>-r win-x64</c> Host publish.
|
||||
/// </summary>
|
||||
public const string WorkerUnderTestVariable = "OTOPCUA_SCRIPTWORKER_TEST_PATH";
|
||||
|
||||
/// <summary>The worker entry named by <see cref="WorkerUnderTestVariable"/>, or null for the built one.</summary>
|
||||
public static string? WorkerUnderTest
|
||||
=> Environment.GetEnvironmentVariable(WorkerUnderTestVariable) is { Length: > 0 } path ? path : null;
|
||||
|
||||
/// <summary>Options for a single-shard runner with short budgets, so the containment tests run in seconds.</summary>
|
||||
public static ScriptingOptions Options(int shards = 1, TimeSpan? hardGrace = null, int quarantineAfterKills = 2,
|
||||
int probation = 20, TimeSpan? unavailableGrace = null, string? workerPath = null, long heapLimit = 256L * 1024 * 1024,
|
||||
@@ -50,7 +60,7 @@ internal static class Scripts
|
||||
QuarantineAfterKills = quarantineAfterKills,
|
||||
IsolationProbationRuns = probation,
|
||||
UnavailableGrace = unavailableGrace ?? TimeSpan.FromSeconds(30),
|
||||
ExecutablePath = workerPath,
|
||||
ExecutablePath = workerPath ?? WorkerUnderTest,
|
||||
HeapLimitBytes = heapLimit,
|
||||
PeCacheDir = peCacheDir,
|
||||
IsolationIdleTimeout = isolationIdle ?? ScriptWorkerOptions.DefaultIsolationIdleTimeout,
|
||||
|
||||
Reference in New Issue
Block a user