Adds a single global concurrency cap on the data-plane dispatch path:
- orchestrator-core::gate::ExecutionGate wraps tokio::Semaphore.
Non-blocking try_acquire — no queue. PICLOUD_MAX_CONCURRENT_EXECUTIONS
env var (default 32) sets the cap.
- LocalExecutorClient acquires a permit before spawn_blocking; the
permit drops with the future so the slot returns automatically.
- On refusal, ExecError::Overloaded { retry_after_secs: 1 } surfaces
upward. ApiError::IntoResponse already maps that to 503 with a
Retry-After header (landed in the previous commit alongside the
variant itself).
- picloud binary constructs the gate once at build_app and shares it
with LocalExecutorClient.
The cap exists so a Rhai script storm can't drain the blocking-thread
pool — pushing back hard beats letting requests pile up against a
finite worker count. Per-app / per-script caps stay deferred until a
real workload demands them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
21 lines
753 B
Rust
21 lines
753 B
Rust
//! Per-node event ingress and dispatch.
|
|
//!
|
|
//! Owns the data-plane request path:
|
|
//! inbound event → resolve script → call `ExecutorClient::execute`
|
|
//!
|
|
//! Does not import `executor-core` types in its public surface beyond the
|
|
//! transport DTOs (`ExecRequest`/`ExecResponse`). The `ExecutorClient`
|
|
//! trait is the seam that lets the orchestrator call executor logic
|
|
//! in-process (single-node) or over HTTP (cluster).
|
|
|
|
pub mod api;
|
|
pub mod client;
|
|
pub mod gate;
|
|
pub mod resolver;
|
|
pub mod routing;
|
|
|
|
pub use api::{data_plane_router, user_routes_router, DataPlaneState};
|
|
pub use client::{ExecutorClient, LocalExecutorClient, RemoteExecutorClient};
|
|
pub use gate::{AcquireError, ExecutionGate};
|
|
pub use resolver::{ResolverError, ScriptResolver};
|