Skip to content

Split Msg into transport envelope and future - #3040

Open
plajjan wants to merge 1 commit into
mainfrom
msg-future-split
Open

Split Msg into transport envelope and future#3040
plajjan wants to merge 1 commit into
mainfrom
msg-future-split

Conversation

@plajjan

@plajjan plajjan commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

One B_Msg object used to play three roles: the mailbox envelope carrying a call to an actor, that actor's activation frame while the call runs, and the future the caller awaits. Three roles with different owners and different lifetimes in one allocation. This splits it into two objects, and the names land where they belong: B_Msg now denotes the message itself, the transport envelope, while the awaitable becomes Future[A] with C type B_Future.

The envelope is a hand-written RTS type not exposed to Acton source. The future keeps the surface role: source annotating Msg[A] must now say Future[A], but generated code treats the type opaquely so there is no behavioral change. The future gains an explicit result state (pending, value, exception) instead of encoding it in the continuation field. An async call allocates one of each and links them; the dispatch loop freezes results into the future and wakes its waiters. Both objects serialize under their own class ids for the distributed backend, and a dead persistence branch for the awaited future is removed since recovery replays a parked actor's whole turn.

A new dev-guide page (runtime/messages.md) documents the design: the two roles and lifetimes, why the per-actor memory model forces the separation, and how the split shows up in DB persistence.

The await semantics tests carry docstrings describing the RTS paths they exercise; those are updated to the split terminology, with the test bodies untouched.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36b86adb72

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread base/builtin/registration.h
@plajjan
plajjan force-pushed the msg-future-split branch 2 times, most recently from fe87339 to 4d19f72 Compare July 24, 2026 20:15
One B_Msg object used to play three roles: the mailbox envelope carrying a
call to an actor, that actor's activation frame while the call runs, and
the future the caller awaits. Three roles with two different owners and
two different lifetimes in one allocation. This splits it into two
objects, and the names land where they belong: B_Msg now denotes the
message itself — the transport envelope — and the awaitable becomes
Future[A] / B_Future.

- B_Msg is the transport envelope, a hand-written RTS type not exposed to
  Acton source: $next linkage, $to, $cont, $baseline, value, and a $fut
  link to the future it fulfills. The actor mailbox fields become
  $msg/$msg_tail/$msg_lock/$outgoing, typed B_Msg; the compiler's prim
  environment types those slots so generated actor headers agree with the
  RTS, and builtin.h forward-declares B_Msg for generated code.

- The future keeps the surface role under its proper name: with the
  envelope split out, what remains of Msg[A] is precisely the future an
  async call returns, so the surface type becomes Future[A] and its C
  type B_Future. It keeps $waiting/$wait_lock (the waiter list) and gains
  an explicit $state (FUT_PENDING/FUT_VALUE/FUT_EXCEPTION) replacing the
  old encoding of result state in the $cont field.

$ASYNC/$AFTER allocate one of each and link them via env->$fut; the
dispatch loop freezes results into the future and wakes its waiters. The
waiter helpers (ADD_waiting, FREEZE_waiting, $AWAIT) take the future.

The rename is user-visible (source annotating Msg[A] must say Future[A])
but behavior-neutral: generated code treats the future opaquely, only
calling $ASYNC/$AWAIT/$AFTER. The rename portions in the compiler passes,
the lib-test fixtures, net.ext.c, function.h and __builtin__.act are
mechanical token substitutions. In the class id table the future's id is
FUTURE_ID and the envelope gets its own preassigned MSG_ID, like the
other RTS types.

With --db, both kinds of row live in MSGS_TABLE and recovery branches on
the class id to allocate the right struct. serialize_msg/serialize_future
are split accordingly. The dead $waitsfor persistence branch is dropped:
it is provably NULL at every serialize point, since recovery replays a
parked actor's whole turn from the envelope at its mailbox head.

After envelopes carry no future at all: "after" is a statement, its
value cannot be bound or awaited (the parser rejects it), so the future
$AFTER used to allocate was bound by generated code into a dead
temporary and dropped, once per timer. The AFTER prims are now typed to
return None, $AFTER returns B_None and leaves $fut NULL, and the
dispatch loop skips result delivery for a NULL future. Timer handling
deals purely in envelopes.

A dev-guide page (runtime/messages.md) documents the design: the two
roles and lifetimes, why the per-actor memory model forces the
separation, how $ASYNC links the two, and how the split shows up in DB
persistence. The await semantics tests' docstrings are updated to the
split terminology (waiter lists, freezing and result state belong to
the future); the test bodies are unchanged.
@plajjan
plajjan force-pushed the msg-future-split branch from 4d19f72 to c135198 Compare July 26, 2026 09:08
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