Skip to content

Bound the Link relay's resources, attachments and closures - #488

Merged
SaladDay merged 2 commits into
feature/agent-outside-sandboxfrom
aos/relay-capacity
Oct 7, 2026
Merged

SaladDay merged 2 commits into
feature/agent-outside-sandboxfrom
aos/relay-capacity

Conversation

@SaladDay

@SaladDay SaladDay commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Core will embed one Link relay (cutover PR2), and every sandbox and agent host will dial it. The relay bounded only per-link streams, pending renewals and queued answers. Serve peers, attachments and pending AttachmentClosed events grew without limit.

Change (internal/sandboxlink/relay):

  • One counter mechanism, checked under the relay lock before the Authority is called, refuses admission beyond capacity with LimitExceeded and leaves no state.
  • Resources (4096): the per-resource maps become one record that holds its slot while the relay holds anything for it (serve peer, Hello being decided, attachment or unwritten event). A reconnect reuses it; one serve link per resource bounds serve links too.
  • Attachments (16384): an Open of an unknown attachment reserves a reference-counted slot that covers the attachment and its later AttachmentClosed events, so pending events are bounded by construction and never dropped for capacity.
  • Attach links (4096): same counter.
  • Values are constants, sized from measured idle cost for one Core running at most 1024 executions (under 500 MiB at capacity).

Behavior changes:

  • RevokeResource discards events it could not deliver: the authority is withdrawn first, so that generation can never reconnect to read them.
  • The relay forgets a resource's generation once it holds nothing for it; the Authority alone then refuses older generations.
  • An Open whose attachment closes while the Authority decides fails with LeaseExpired instead of recreating it.

The wire does not change. docs/sandbox-link-protocol.md (+ zh) states the limits once and updates admission order, closures, staleness, the LimitExceeded row and Verification.

Checks: go test ./internal/sandboxlink/... (with fuzz seeds), go test -race -count=50 ./internal/sandboxlink/relay/, vet, gofmt, darwin/windows builds, make check-names check-docs check-ci.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

The relay held serve peers, attachments and pending AttachmentClosed
events without limit, so peers could grow Core's memory without bound.
Each now takes a slot at admission, before the Authority is consulted,
and a Hello or Open beyond capacity is refused with LimitExceeded and
leaves no state:

- A resource holds one of 4096 slots from the serve Hello that first
  names it while the relay holds anything for it: its serve peer, a
  Hello being decided, an attachment or an unwritten event. Its
  generation, serve peer and events now live in one record, so the
  generation map no longer grows with every resource ever served.
- An attachment holds one of 16384 slots until it is closed and its
  AttachmentClosed events are written or discarded, so pending events
  are bounded by construction.
- An attach link holds one of 4096 slots until it ends.

RevokeResource now discards the events its revoked serve peer could
not read, since its authority is withdrawn and it cannot reconnect;
otherwise every destroyed sandbox would keep its slots. An Open of an
attachment that closes while the Authority decides fails with
LeaseExpired instead of recreating it without a slot.
@SaladDay
SaladDay merged commit 0a0328c into feature/agent-outside-sandbox Oct 7, 2026
19 checks passed
@SaladDay
SaladDay deleted the aos/relay-capacity branch October 7, 2026 13:28
A serve Hello now takes one of two Hello slots of its resource until it
is decided, so later Hellos for a held resource no longer wait on the
Authority without limit. An Open takes a stream slot of its attach link
before the Authority decides and keeps it until its decision ends, even
when the peer resets the stream, and an attach link keeps its slot until
every stream and renewal it carried has finished. An Open whose
attachment closes while it is decided now fails with LeaseExpired even
when another Open has created an attachment under the same ID since.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant