Skip to content

[Prototype] Rewrite JSONRPCConnection as an actor with AsyncStream#50

Draft
rintaro wants to merge 1 commit into
swiftlang:mainfrom
rintaro:jsonrpcconnection-actor
Draft

[Prototype] Rewrite JSONRPCConnection as an actor with AsyncStream#50
rintaro wants to merge 1 commit into
swiftlang:mainfrom
rintaro:jsonrpcconnection-actor

Conversation

@rintaro
Copy link
Copy Markdown
Member

@rintaro rintaro commented May 20, 2026

Experimenting.

Three AsyncStreams.

AsyncStream<OutgoingItem> (outgoingContinuation)
Serializes all outgoing work items (notifications, requests, replies) from any caller into the actor. Its Continuation is a let property, making send/sendReply fully nonisolated — callers never have to hop to the actor just to enqueue a message. The fire-and-forget actor task drains it in strict FIFO order, guaranteeing message ordering without a dispatch queue.

AsyncStream<Data> (sendContinuation)
Decouples the actor-isolated encoding step from the blocking sendFD.write. The actor encodes a message and yields the bytes synchronously; the Task.detached send loop picks them up and blocks the thread waiting on I/O, without ever touching the actor. This is why two "send" streams are needed rather than one: the blocking write must not hold the actor's executor.

AsyncStream<Data> (receiveStream, created in _start)
Same idea on the read side. The Task.detached reader blocks on receiveFD.read, yields complete framed messages, and the actor-isolated receiveLoopTask picks them up to decode and dispatch. The stream is the hand-off point between the blocking I/O thread and the actor.

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