Files
orca/src/shared/workspace-session-contested-primary-host.ts
T
Jinwoo Hong 4005884fe5 Main routes a project registered on two machines to the same owner the window saves to (dark, layout-owner build only) (#30196)
* refactor: move the contested-workspace primary-host rule to src/shared (move only)

* fix(layout-owner): main routes a twin repo's workspace to the same primary host the window saves to

* fix(layout-owner): route a twin repo's single-host worktree to the host that holds it; hydrate twins the same way

* fix(layout-owner): twin-repo routing counts only runtime owners from the catalog, matching the window; one table checks both sides

* fix: drop the duplicate layout-owner switch import after merging main

* fix: type the twin-routing fixture and partition set
2026-10-18 01:41:22 -07:00

34 lines
1.6 KiB
TypeScript

import {
LOCAL_EXECUTION_HOST_ID,
parseExecutionHostId,
type ExecutionHostId
} from './execution-host'
import { workspaceSessionPartitionHostId } from './workspace-session-partition-owner'
/** The partition a host's session rows live in: every non-'local' host owns its own. */
export function sessionPartitionHostFor(hostId: ExecutionHostId): ExecutionHostId {
return workspaceSessionPartitionHostId(hostId)
}
/** Distinct partitions a set of claimants spans. Fewer than two means persistence cannot tell the
* claimants apart, so the id keeps its uncontested routing. */
export function contestedPartitionHosts(claimed: Iterable<ExecutionHostId>): ExecutionHostId[] {
return [...new Set([...claimed].map(sessionPartitionHostFor))]
}
/** Stable owner of a contested id: 'local' when it is a claimant, then any non-runtime host, then
* the lowest host id.
* Deliberately not the active host — a primary that followed navigation would migrate the same
* rows between partitions on every workspace switch. And deliberately not plain sort order once
* 'local' is out: a `runtime:` environment id rotates across relay restarts, so ranking it last
* keeps a re-created environment from taking a stable host's rows into its partition. */
export function pickPrimaryHostForClaims(hostIds: Iterable<ExecutionHostId>): ExecutionHostId {
const sorted = [...hostIds].sort()
return (
sorted.find((hostId) => hostId === LOCAL_EXECUTION_HOST_ID) ??
sorted.find((hostId) => parseExecutionHostId(hostId)?.kind !== 'runtime') ??
sorted[0] ??
LOCAL_EXECUTION_HOST_ID
)
}