(params: {
record: WorkspaceTurnTaskHandleRecord;
next: WorkspaceTurnTaskHandleRecord;
waiterSettlement:
| { status: "completed"; result: WorkspaceTurnWaitResult }
| { status: "error"; error: Error };
})
| 4750 | } |
| 4751 | |
| 4752 | private async settleWorkspaceTurn(params: { |
| 4753 | record: WorkspaceTurnTaskHandleRecord; |
| 4754 | next: WorkspaceTurnTaskHandleRecord; |
| 4755 | waiterSettlement: |
| 4756 | | { status: "completed"; result: WorkspaceTurnWaitResult } |
| 4757 | | { status: "error"; error: Error }; |
| 4758 | }): Promise<void> { |
| 4759 | assert( |
| 4760 | params.next.handleId === params.record.handleId, |
| 4761 | "settleWorkspaceTurn requires stable handleId" |
| 4762 | ); |
| 4763 | assert( |
| 4764 | params.next.workspaceId === params.record.workspaceId, |
| 4765 | "settleWorkspaceTurn requires stable workspaceId" |
| 4766 | ); |
| 4767 | |
| 4768 | // The settlement lock only persists durable state and resolves waiters. The terminal wake-up is |
| 4769 | // enqueued AFTER the lock is released (no sendMessage / notifier work while holding the lock). |
| 4770 | const pendingNotify = await this.workspaceTurnSettlementLocks.withLock( |
| 4771 | params.record.handleId, |
| 4772 | async (): Promise< |
| 4773 | | { kind: "notify"; outcome: TerminalAttentionOutcome; title?: string } |
| 4774 | | { kind: "drain_pending" } |
| 4775 | | null |
| 4776 | > => { |
| 4777 | const current = await this.taskHandleStore.getWorkspaceTurn( |
| 4778 | params.record.ownerWorkspaceId, |
| 4779 | params.record.handleId |
| 4780 | ); |
| 4781 | if (current == null) { |
| 4782 | return null; |
| 4783 | } |
| 4784 | assert( |
| 4785 | current.workspaceId === params.record.workspaceId, |
| 4786 | "settleWorkspaceTurn requires current record to match workspaceId" |
| 4787 | ); |
| 4788 | |
| 4789 | if (this.isTerminalWorkspaceTurnStatus(current.status)) { |
| 4790 | const active = this.activeWorkspaceTurnHandleByWorkspaceId.get(params.record.workspaceId); |
| 4791 | if ( |
| 4792 | active?.handleId === params.record.handleId && |
| 4793 | active.ownerWorkspaceId === params.record.ownerWorkspaceId |
| 4794 | ) { |
| 4795 | this.activeWorkspaceTurnHandleByWorkspaceId.delete(params.record.workspaceId); |
| 4796 | } |
| 4797 | this.settleWorkspaceTurnWaiters( |
| 4798 | current.handleId, |
| 4799 | current.status === "completed" |
| 4800 | ? { status: "completed", result: this.buildWorkspaceTurnWaitResult(current) } |
| 4801 | : { |
| 4802 | status: "error", |
| 4803 | error: new Error( |
| 4804 | current.error ?? |
| 4805 | (current.status === "interrupted" |
| 4806 | ? "Workspace turn interrupted" |
| 4807 | : "Workspace turn failed") |
| 4808 | ), |
| 4809 | } |
no test coverage detected