src/failover-types.tsTypeScript
@@ -0,0 +1,76 @@
1+
export type Region = "east" | "west";2+
export type FailoverPhase = "planned" | "source-fenced" | "target-writable" | "traffic-shifted" | "complete";3+
4+
export interface HealthSample {5+
observerId: string;6+
healthy: boolean;7+
sampledAt: Date;8+
}9+
10+
export interface FailoverState {11+
activeRegion: Region;12+
epoch: number;13+
operationId?: string;14+
phase?: FailoverPhase;15+
sourceSafePosition: number;16+
}17+
18+
export interface FailoverCommandIdentity {19+
operationId: string;20+
}21+
22+
export interface FailoverDependencies {23+
health: {24+
recent(region: Region): Promise<HealthSample[]>;25+
};26+
lease: {27+
acquire(operationId: string): Promise<{28+
fencingToken: number;29+
release(): Promise<void>;30+
}>;31+
};32+
replication: {33+
status(region: Region): Promise<{34+
lagSeconds: number;35+
appliedPosition: number;36+
}>;37+
};38+
regions: {39+
setReadOnly(40+
region: Region,41+
fencingToken: number,42+
): Promise<{ finalSafePosition: number }>;43+
setWritable(region: Region, fencingToken: number): Promise<void>;44+
setReadOnlyForOperation(45+
region: Region,46+
fencingToken: number,47+
identity: FailoverCommandIdentity,48+
): Promise<{ finalSafePosition: number }>;49+
setWritableForOperation(50+
region: Region,51+
fencingToken: number,52+
identity: FailoverCommandIdentity,53+
): Promise<void>;54+
};55+
traffic: {56+
shift(region: Region, fencingToken: number): Promise<void>;57+
shiftForOperation(58+
region: Region,59+
fencingToken: number,60+
identity: FailoverCommandIdentity,61+
): Promise<void>;62+
};63+
state: {64+
load(): Promise<FailoverState>;65+
save(state: FailoverState, fencingToken: number): Promise<void>;66+
};67+
operationLock: {68+
runExclusive<T>(work: () => Promise<T>): Promise<T>;69+
};70+
ids: {71+
next(): string;72+
};73+
telemetry: {74+
replicationLag(seconds: number): void;75+
};76+
}