[P0-27] Add one total concurrency count to Sento dispatchers and pinned actors #139

Open
opened 2026-09-02 17:26:33 +00:00 by nsaspy · 0 comments
Owner

Problem

StarIntel needs multiple Sento dispatchers/pinned actors for isolation, but Sento currently lets each named dispatcher realize its own :workers count independently. Those local counts multiply because there is no aggregate Sento execution-lane ceiling.

This issue is now explicitly not a router rewrite or new workload DSL.

Exact Sento baseline

Current starintel-server/qlfile.lock pins:

mdbergmann/cl-gserver@6a510c5b58469e72e6363bd3a6059d80b9a5c320

At that revision:

  • shared dispatcher with N workers -> N dispatcher-worker actors;
  • every dispatcher worker is internally :pinned -> one message-box/bt thread each;
  • ordinary :pinned actor -> one message-box/bt thread;
  • ordinary actor on a named/shared dispatcher -> message-box/dp, no owned thread;
  • router -> strategy + routee forwarding only, no execution thread.

Therefore the correct accounting unit is one Sento execution lane.

Preserve Sento behavior

Keep unchanged:

  • named shared dispatchers;
  • each dispatcher's local :workers value;
  • dynamic register-new-dispatcher;
  • router :random;
  • router :round-robin;
  • custom count-to-index strategies;
  • message-box/dp semantics;
  • message-box/bt / :pinned semantics;
  • existing dispatcher/router tests.

The missing invariant is only:

sum(all live Sento execution-lane ownership) <= numeric Sento grant from #34/#177 process planner

Lane costs

owner cost
shared-dispatcher worker 1
N-worker shared dispatcher N
ordinary :pinned actor 1
ordinary dispatcher-backed actor 0
router 0
routee membership 0

Internally pinned dispatcher workers must be charged once, not once through the dispatcher and again through generic pinned-actor accounting.

Required behavior

Startup

Preflight the sum of configured shared-dispatcher workers before the first dispatcher worker thread starts.

Example: :shared=4 + :storage=4, Sento grant=6 -> typed failure, zero worker realization.

Dynamic dispatcher

Reserve N atomically before creating N workers. If insufficient capacity exists, create no dispatcher workers. Partial construction failure rolls back the complete reservation.

Ordinary pinned actor

Reserve one lane immediately before message-box/bt starts. If free capacity is zero, fail before thread creation.

Dispatcher-backed actor/router

No additional lane reservation.

Stop/restart

Release exactly once on confirmed owner termination, not merely stop request. Restarting the processing thread of the same live pinned mailbox does not consume another lane.

Diagnostics

Expose at minimum:

  • granted Sento concurrency;
  • used;
  • free;
  • owner -> lane count;
  • owner kind / dispatcher ID or actor path for diagnostics.

This is read-only capacity input for #36. #36 still owns queue admission, overload, drop/block/reject, and prefetch behavior.

Process-budget dependency

#34 / Auto-Research #176/#177 remains the one process-wide thread authority. Sento receives a numeric grant after non-Sento thread demands/control reserve are planned. Do not add a competing user-facing max-thread configuration.

Also retire StarIntel's custom shared dispatcher ID :pinned; Sento reserves :pinned as dedicated-thread mailbox behavior before named-dispatcher lookup.

Canonical ARDR authority

  • Research: lost-rob0t/starintel-auto-research/roam/research/ardr-issues/ARDR-ISSUE-188-workload-dispatchers-router-pools.org
  • Design: lost-rob0t/starintel-auto-research/roam/design/star-server/STAR-SERVER-042-workload-dispatchers-router-pools.org
  • Auto-Research #188 / #189

The stable Org IDs/paths are retained; their earlier workload-topology-first text is superseded by the deeper Sento backend analysis.

Proposed first implementation slice — PENDING OPERATOR APPROVAL

Slice 1: pure concurrency ledger + configured-dispatcher demand preflight.

Mandatory RED-first targets:

  1. configured workers 4 + 4 under grant 6 -> typed over-capacity failure;
  2. 4 + 2 under grant 6 -> success, used=6, free=0;
  3. duplicate owner reservation rejected;
  4. unknown/duplicate release cannot corrupt count;
  5. deterministic owner snapshot.

Follow-on REDs:

  • 4-worker shared dispatcher charges exactly 4 although workers are internally pinned;
  • construction failure leaks zero capacity;
  • exhausted grant prevents ordinary pinned actor thread creation;
  • dispatcher-backed actor changes count by zero;
  • router creation/add-routee changes count by zero;
  • pinned actor/dispatcher stop releases exactly once;
  • pinned mailbox processing-thread restart adds zero capacity;
  • existing random/round-robin/custom router behavior remains unchanged.

Acceptance criteria

  • same Sento router/dispatcher semantics, now bounded by one aggregate total;
  • per-dispatcher worker counts remain supported;
  • total Sento actor-execution concurrency can never exceed its process-plan grant;
  • no double count of dispatcher workers;
  • no reservation leaks on failure/stop/restart;
  • no actor-count or routee-count proxy for actual concurrency;
  • no new StarLang syntax or external supervisor;
  • process-wide #177 authority remains canonical.

Implementation authorization

PENDING / AWAITING_OPERATOR_APPROVAL

Research/design readiness and this issue update do not authorize implementation.

## Problem StarIntel needs multiple Sento dispatchers/pinned actors for isolation, but Sento currently lets each named dispatcher realize its own `:workers` count independently. Those local counts multiply because there is no aggregate Sento execution-lane ceiling. This issue is now explicitly **not** a router rewrite or new workload DSL. ## Exact Sento baseline Current `starintel-server/qlfile.lock` pins: `mdbergmann/cl-gserver@6a510c5b58469e72e6363bd3a6059d80b9a5c320` At that revision: - shared dispatcher with N workers -> N dispatcher-worker actors; - every dispatcher worker is internally `:pinned` -> one `message-box/bt` thread each; - ordinary `:pinned` actor -> one `message-box/bt` thread; - ordinary actor on a named/shared dispatcher -> `message-box/dp`, no owned thread; - router -> strategy + routee forwarding only, no execution thread. Therefore the correct accounting unit is one **Sento execution lane**. ## Preserve Sento behavior Keep unchanged: - named shared dispatchers; - each dispatcher's local `:workers` value; - dynamic `register-new-dispatcher`; - router `:random`; - router `:round-robin`; - custom count-to-index strategies; - `message-box/dp` semantics; - `message-box/bt` / `:pinned` semantics; - existing dispatcher/router tests. The missing invariant is only: `sum(all live Sento execution-lane ownership) <= numeric Sento grant from #34/#177 process planner` ## Lane costs | owner | cost | |---|---:| | shared-dispatcher worker | 1 | | N-worker shared dispatcher | N | | ordinary `:pinned` actor | 1 | | ordinary dispatcher-backed actor | 0 | | router | 0 | | routee membership | 0 | Internally pinned dispatcher workers must be charged **once**, not once through the dispatcher and again through generic pinned-actor accounting. ## Required behavior ### Startup Preflight the sum of configured shared-dispatcher workers before the first dispatcher worker thread starts. Example: `:shared=4 + :storage=4`, Sento grant=6 -> typed failure, zero worker realization. ### Dynamic dispatcher Reserve N atomically before creating N workers. If insufficient capacity exists, create no dispatcher workers. Partial construction failure rolls back the complete reservation. ### Ordinary pinned actor Reserve one lane immediately before `message-box/bt` starts. If free capacity is zero, fail before thread creation. ### Dispatcher-backed actor/router No additional lane reservation. ### Stop/restart Release exactly once on confirmed owner termination, not merely stop request. Restarting the processing thread of the same live pinned mailbox does not consume another lane. ## Diagnostics Expose at minimum: - granted Sento concurrency; - used; - free; - owner -> lane count; - owner kind / dispatcher ID or actor path for diagnostics. This is read-only capacity input for #36. #36 still owns queue admission, overload, drop/block/reject, and prefetch behavior. ## Process-budget dependency #34 / Auto-Research #176/#177 remains the one process-wide thread authority. Sento receives a numeric grant after non-Sento thread demands/control reserve are planned. Do **not** add a competing user-facing max-thread configuration. Also retire StarIntel's custom shared dispatcher ID `:pinned`; Sento reserves `:pinned` as dedicated-thread mailbox behavior before named-dispatcher lookup. ## Canonical ARDR authority - Research: `lost-rob0t/starintel-auto-research/roam/research/ardr-issues/ARDR-ISSUE-188-workload-dispatchers-router-pools.org` - Design: `lost-rob0t/starintel-auto-research/roam/design/star-server/STAR-SERVER-042-workload-dispatchers-router-pools.org` - Auto-Research #188 / #189 The stable Org IDs/paths are retained; their earlier workload-topology-first text is superseded by the deeper Sento backend analysis. ## Proposed first implementation slice — PENDING OPERATOR APPROVAL **Slice 1: pure concurrency ledger + configured-dispatcher demand preflight.** Mandatory RED-first targets: 1. configured workers 4 + 4 under grant 6 -> typed over-capacity failure; 2. 4 + 2 under grant 6 -> success, `used=6`, `free=0`; 3. duplicate owner reservation rejected; 4. unknown/duplicate release cannot corrupt count; 5. deterministic owner snapshot. Follow-on REDs: - 4-worker shared dispatcher charges exactly 4 although workers are internally pinned; - construction failure leaks zero capacity; - exhausted grant prevents ordinary pinned actor thread creation; - dispatcher-backed actor changes count by zero; - router creation/add-routee changes count by zero; - pinned actor/dispatcher stop releases exactly once; - pinned mailbox processing-thread restart adds zero capacity; - existing random/round-robin/custom router behavior remains unchanged. ## Acceptance criteria - same Sento router/dispatcher semantics, now bounded by one aggregate total; - per-dispatcher worker counts remain supported; - total Sento actor-execution concurrency can never exceed its process-plan grant; - no double count of dispatcher workers; - no reservation leaks on failure/stop/restart; - no actor-count or routee-count proxy for actual concurrency; - no new StarLang syntax or external supervisor; - process-wide #177 authority remains canonical. ## Implementation authorization `PENDING / AWAITING_OPERATOR_APPROVAL` Research/design readiness and this issue update do not authorize implementation.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/starintel-server#139
No description provided.