Skip to content

Centralize macOS protocol connection ownership - #3392

Merged
breznknecht merged 1 commit into
mainfrom
codex/issue-3303-protocol-connection-owner
Sep 16, 2026
Merged

breznknecht merged 1 commit into
mainfrom
codex/issue-3303-protocol-connection-owner

Conversation

@breznknecht

Copy link
Copy Markdown
Collaborator

TL;DR

The macOS frontend now gives each protocol connection one main-actor owner for ordered delivery, replacement, and teardown. Startup and reconnect use the same lifecycle, so retired work cannot affect the active encoder.

Closes #3303

Context

AppDelegate previously coordinated the encoder, reader, capacity-one handoff, and consumer through separate fields and duplicated their assembly for startup and reconnect. That split ownership made teardown order and retired callbacks difficult to reason about.

Changes

  • Add ProtocolConnection as the single owner of the encoder, reader, capacity-one handoff, and consumer task.
  • Route initial startup and reconnect through the same replacement operation.
  • Cancel admission and consumer work before starting replacement delivery, while keeping delayed retired callbacks bound to the retired encoder.
  • Keep stop idempotent and nonblocking on the main actor. The implementation does not claim that task cancellation interrupts a blocked FileHandle read; transport closure or read completion releases the retired reader.
  • Remove the duplicate AppDelegate connection fields, assembly code, and the obsolete reconnect workflow.
  • Add controlled-pipe lifecycle coverage for startup, FIFO delivery and decode failures, blocked admission, replacement, delayed retired callbacks, blocked reads, failed replacement construction, and idempotent stop without timing sleeps.

Verification

  • mix swift.build -- -project macos/Minga.xcodeproj -scheme Minga -configuration Debug -derivedDataPath macos/DerivedData CODE_SIGNING_ALLOWED=NO -quiet test
  • mix protocol.gen --check
  • make lint
  • git diff --check origin/main...HEAD
  • Focused code review: PASS
  • Final acceptance review after blocker fixes: PASS

Acceptance Criteria Addressed

  1. Startup and reconnect share one lifecycle with one active consumer. ✅
  2. FIFO frame and decode-failure delivery retains capacity-one admission. ✅
  3. Replacement cancels retired admission and consumer work before new delivery, and delayed retired callbacks cannot disconnect the replacement. ✅
  4. Stop is idempotent, wakes blocked admission, and does not wait for a blocked pipe read on the main actor. ✅
  5. Development disconnect, bundled restart, recovery generation, and resize behavior remain unchanged. ✅
  6. Controlled-pipe lifecycle tests cover startup, delivery, replacement, delayed callbacks, and teardown through the shared assembly path. ✅

@breznknecht
breznknecht merged commit 4e95c16 into main Sep 16, 2026
11 checks passed
@breznknecht
breznknecht deleted the codex/issue-3303-protocol-connection-owner branch September 16, 2026 16:16
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.

Protocol connections own ordered delivery and teardown

1 participant