From e3757357963f8007ed3a0f874ac3a0017749795a Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Sat, 30 May 2026 20:10:05 +0200 Subject: [PATCH] docs(blueprint+gate): drop hstore from Tech Stack; note gate-vs-timeout interaction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two review-pass nits from the v1.1.0-foundation review: - Blueprint §6 Tech Stack table still listed the database as "PostgreSQL + hstore" with an hstore-for-KV rationale — directly contradicting the §8.1 KV rewrite that explicitly rejected hstore in favour of JSONB. Updates the row so the high-level summary matches the §8.1 reasoning. - LocalExecutorClient::execute now documents the permit-vs-timeout interaction: when tokio::time::timeout fires the future drops and the permit returns, but the detached spawn_blocking thread keeps running until the Rhai script winds down. In-use blocking threads can briefly exceed the gate's permit count after a timeout. Calling it out so future readers don't read the implementation as buggy. No behaviour change. Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/orchestrator-core/src/client.rs | 10 ++++++++-- serverless_cloud_blueprint.md | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/orchestrator-core/src/client.rs b/crates/orchestrator-core/src/client.rs index feaca81..3b2b218 100644 --- a/crates/orchestrator-core/src/client.rs +++ b/crates/orchestrator-core/src/client.rs @@ -57,8 +57,14 @@ impl ExecutorClient for LocalExecutorClient { timeout: Duration, ) -> Result { // Acquire before spending any wall-clock budget. The permit is - // held until this future returns; spawn_blocking inherits the - // gating via the captured `_permit`. + // held by this future; on `tokio::time::timeout` firing, the + // future drops and the permit returns to the pool — but the + // detached `spawn_blocking` thread keeps running until the + // Rhai script finishes (or panics). So in-use blocking threads + // can briefly exceed the gate's permit count after a timeout. + // That is intentional: a new admission can be served while the + // already-doomed script winds down, which is preferable to + // wedging the slot for the worst-case timeout duration. let _permit = self.gate .try_acquire() diff --git a/serverless_cloud_blueprint.md b/serverless_cloud_blueprint.md index f3c2341..75877c0 100644 --- a/serverless_cloud_blueprint.md +++ b/serverless_cloud_blueprint.md @@ -661,7 +661,7 @@ users.set_permissions(user_id, { |-------|-----------|-----------| | **Orchestrator** | Rust + Axum | Performance, safety, async-first; minimal overhead | | **Dashboard** | Alpine.js + vanilla HTML/CSS | Zero dependencies, simple to deploy, fast enough for MVP | -| **Database** | PostgreSQL + hstore | Robust ACID database; hstore extension for lightweight KV (v1.1) | +| **Database** | PostgreSQL 15+ (`pgcrypto`) | Robust ACID database; JSONB carries data-plane values (v1.1+). See §8.1. | | **Container Runtime** | Docker (Docker daemon) | Industry standard, simple CLI | | **Executor Image** | Alpine Linux + Rhai | Minimal image size (~50-100MB), fast startup | | **Scripting** | Rhai | Lightweight, embedded-friendly, safe by default |