You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Child of #327 (enterprise deployment framework — explicitly bare-metal + Aspire). Sibling of #371 (shared Deno KV Connect). Together these are the two arms of an environment-aware shared-cache provisioner. Validated live in eis-chat (rickylabs/eis-chat#133).
Problem
The Aspire generator provisions a shared cache only as a Docker container — Redis/Garnet via addContainer (ghcr.io/microsoft/garnet), and the historical Deno KV Connect path was also a container (ghcr.io/denoland/denokv). On a Docker-less host (e.g. Windows bare metal — a first-class target per #327/#364) there is no way to stand up a shared cache/queue: DenoKv no-ops (file-backed, per-process), and Redis/Garnet require Docker. Result in multi-process mode: workers-api (enqueue) and the workers processor (listen) each open their own per-process Deno KV, so jobs are never delivered (split-brain queue).
Confirmed: git log --all -S "GarnetServer" / -S "Microsoft.Garnet" in netscript-start = 0 commits. Neither netscript-start nor the SDK has ever run Garnet as an executable — only the container integration + an External (BYO-URL) mode. So there is no Docker-less managed shared cache today.
Proposal — Garnet as an Aspire EXECUTABLE, self-provisioned
Garnet is .NET-native and runs on Windows bare metal without Docker. Since the Aspire AppHost is itself .NET-hosted (the SDK is guaranteed present), the generator can self-provision it:
Ship a local tool manifest (.config/dotnet-tools.json) pinning garnet-server (the Microsoft-published, verified NuGet tool — dotnet tool search garnet → garnet-server), and dotnet tool restore at AppHost startup; then register addExecutable('garnet', 'garnet-server', ['--port','6379','--bind','127.0.0.1', ...]) with a tcp endpoint on 6379. (Or probe + dotnet tool install on first run.)
Inject the connection env into every RequiresKv consumer: GARNET_URI (or services__garnet__tcp__0 / ConnectionStrings__garnet). The SDK already reads these.
The generator's shared-cache selection should be environment-aware: Docker present → Redis/Garnet/denokv container (existing); Docker-less bare metal → Garnet (or Redis) executable via the managed dotnet tool.
No @netscript/kv or @netscript/queue change needed: @netscript/kv/redisRedisKvAdapter + @netscript/queueRedisAdapter (native LPUSH/BRPOPLPUSH, cross-process) already consume GARNET_URI. One requirement to document: each Deno entrypoint that calls getKv() must import '@netscript/kv/redis' (self-registers the adapter) — otherwise getKv() throws "Redis adapter is not registered" once a Garnet URL is present. (The plugin-workers/services entrypoint already does this; a bare background-runtime entrypoint like workers/runtime.ts does not — the generator/docs should surface this.)
Live proof (eis-chat, Docker-less Windows bare metal, .NET 10, @netscript/* alpha.19)
Hand-edited the generated apphost helpers to stand Garnet up as an executable + inject GARNET_URI/REDIS_URI/CACHE_PROVIDER=garnet into workers-api + the workers processor, and added import 'jsr:@netscript/kv@0.0.1-alpha.19/redis' to workers/runtime.ts. Then, via the Aspire CLI/MCP (aspire start, list_resources, execute_resource_command, list_console_logs):
workers-api + workers: both Running/Healthy, both WaitFor(garnet), both carry GARNET_URI.
Triggered a job on workers-api (POST /api/v1/workers/jobs/<id>/trigger, the enqueue side) → the separate workers processor logged Processing job … (trigger: api) → Executing job … via WorkerPool. Cross-process delivery over the shared Garnet queue works — the exact hop the split-brain Deno KV was dropping.
(The health-check job then failed with Module not found …/plugins/workers/jobs/health-check.ts — an unrelated thin-plugin-surface gap where the plugin's own job entrypoint isn't vendored; the queue delivered the message correctly. Filed/flagged separately.)
Asks
Generator (packages/cli/.../generate-register-infrastructure.ts): add a Garnet-executable branch (new cache Mode, e.g. Executable/BareMetal) emitting addExecutable('garnet','garnet-server', ...) + tcp endpoint + GARNET_URI/services__garnet__tcp__0 injection into RequiresKv consumers.
Self-provision the tool (.config/dotnet-tools.json + dotnet tool restore, or install-on-first-run) so git clone && aspire start needs no manual dotnet tool install.
Child of #327 (enterprise deployment framework — explicitly bare-metal + Aspire). Sibling of #371 (shared Deno KV Connect). Together these are the two arms of an environment-aware shared-cache provisioner. Validated live in eis-chat (rickylabs/eis-chat#133).
Problem
The Aspire generator provisions a shared cache only as a Docker container — Redis/Garnet via
addContainer(ghcr.io/microsoft/garnet), and the historical Deno KV Connect path was also a container (ghcr.io/denoland/denokv). On a Docker-less host (e.g. Windows bare metal — a first-class target per #327/#364) there is no way to stand up a shared cache/queue:DenoKvno-ops (file-backed, per-process), and Redis/Garnet require Docker. Result in multi-process mode: workers-api (enqueue) and the workers processor (listen) each open their own per-process Deno KV, so jobs are never delivered (split-brain queue).Confirmed:
git log --all -S "GarnetServer"/-S "Microsoft.Garnet"in netscript-start = 0 commits. Neither netscript-start nor the SDK has ever run Garnet as an executable — only the container integration + anExternal(BYO-URL) mode. So there is no Docker-less managed shared cache today.Proposal — Garnet as an Aspire EXECUTABLE, self-provisioned
Garnet is .NET-native and runs on Windows bare metal without Docker. Since the Aspire AppHost is itself .NET-hosted (the SDK is guaranteed present), the generator can self-provision it:
.config/dotnet-tools.json) pinninggarnet-server(the Microsoft-published, verified NuGet tool —dotnet tool search garnet→garnet-server), anddotnet tool restoreat AppHost startup; then registeraddExecutable('garnet', 'garnet-server', ['--port','6379','--bind','127.0.0.1', ...])with a tcp endpoint on 6379. (Or probe +dotnet tool installon first run.)RequiresKvconsumer:GARNET_URI(orservices__garnet__tcp__0/ConnectionStrings__garnet). The SDK already reads these.No
@netscript/kvor@netscript/queuechange needed:@netscript/kv/redisRedisKvAdapter+@netscript/queueRedisAdapter(nativeLPUSH/BRPOPLPUSH, cross-process) already consumeGARNET_URI. One requirement to document: each Deno entrypoint that callsgetKv()mustimport '@netscript/kv/redis'(self-registers the adapter) — otherwisegetKv()throws "Redis adapter is not registered" once a Garnet URL is present. (Theplugin-workers/servicesentrypoint already does this; a bare background-runtime entrypoint likeworkers/runtime.tsdoes not — the generator/docs should surface this.)Live proof (eis-chat, Docker-less Windows bare metal, .NET 10, @netscript/* alpha.19)
Hand-edited the generated apphost helpers to stand Garnet up as an executable + inject
GARNET_URI/REDIS_URI/CACHE_PROVIDER=garnetinto workers-api + the workers processor, and addedimport 'jsr:@netscript/kv@0.0.1-alpha.19/redis'toworkers/runtime.ts. Then, via the Aspire CLI/MCP (aspire start,list_resources,execute_resource_command,list_console_logs):garnetresource: Running / Healthy,garnet-server --port 6379 --bind 127.0.0.1 --memory 1g --index 64m.WaitFor(garnet), both carryGARNET_URI.POST /api/v1/workers/jobs/<id>/trigger, the enqueue side) → the separate workers processor loggedProcessing job … (trigger: api)→Executing job … via WorkerPool. Cross-process delivery over the shared Garnet queue works — the exact hop the split-brain Deno KV was dropping.(The health-check job then failed with
Module not found …/plugins/workers/jobs/health-check.ts— an unrelated thin-plugin-surface gap where the plugin's own job entrypoint isn't vendored; the queue delivered the message correctly. Filed/flagged separately.)Asks
packages/cli/.../generate-register-infrastructure.ts): add a Garnet-executable branch (new cacheMode, e.g.Executable/BareMetal) emittingaddExecutable('garnet','garnet-server', ...)+ tcp endpoint +GARNET_URI/services__garnet__tcp__0injection intoRequiresKvconsumers..config/dotnet-tools.json+dotnet tool restore, or install-on-first-run) sogit clone && aspire startneeds no manualdotnet tool install.import '@netscript/kv/redis'requirement for background-runtime entrypoints.References
NetScriptInfrastructureBuilder.csAddContainerGarnet/AddExternalCache; generatorgenerate-register-infrastructure.tsRedis/Garnet container branch.@netscript/kv@0.0.1-alpha.19application/auto-detect.ts(readsREDIS_URI/GARNET_URI/services__garnet__tcp__0),redis.ts(self-register);@netscript/queue@0.0.1-alpha.19factory/create-queue.tscreateRedisQueue+adapters/redis.adapter.ts.