mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 09:07:40 +00:00
* 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
34 lines
1.6 KiB
TypeScript
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
|
|
)
|
|
}
|