54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
// Auto-generated by speckl-compile from KafkaKRaft
|
|
// DO NOT EDIT MANUALLY — regenerate from .speckdl source
|
|
|
|
export const KafkaKRaftState = {
|
|
Candidate: 'candidate',
|
|
Leader: 'leader',
|
|
} as const;
|
|
export type KafkaKRaftState = typeof KafkaKRaftState[keyof typeof KafkaKRaftState];
|
|
|
|
|
|
|
|
|
|
export class KafkaKRaftMachine {
|
|
currentTerm: number;
|
|
state: KafkaKRaftState;
|
|
votedFor: Option(NodeId);
|
|
log: LogEntry[];
|
|
commitIndex: number;
|
|
nextIndex: Map<NodeId, number>;
|
|
matchIndex: Map<NodeId, number>;
|
|
votesGranted: Set<NodeId>;
|
|
decisionLog: any[] = [];
|
|
|
|
constructor() {
|
|
// No init block defined
|
|
}
|
|
|
|
RequestVote(candidate: NodeId, lastLogTerm: number, lastLogIndex: number) {
|
|
if (!(this.state == KafkaKRaftState.Candidate)) throw new Error('Guard failed: this.state == KafkaKRaftState.Candidate');
|
|
if (!(this.currentTerm >= lastLogTerm)) throw new Error('Guard failed: this.currentTerm >= lastLogTerm');
|
|
this.votesGranted = new Set([...this.votesGranted, candidate]);
|
|
}
|
|
|
|
HandleRequestVoteRequest(candidate: NodeId, candidateTerm: number, lastLogTerm: number, lastLogIndex: number) {
|
|
if (!(this.currentTerm >= candidateTerm)) throw new Error('Guard failed: this.currentTerm >= candidateTerm');
|
|
this.votedFor = Some(candidate);
|
|
}
|
|
|
|
BecomeLeader() {
|
|
if (!(this.state == KafkaKRaftState.Candidate)) throw new Error('Guard failed: this.state == KafkaKRaftState.Candidate');
|
|
if (!(this.votesGranted.size >= 3)) throw new Error('Guard failed: this.votesGranted.size >= 3');
|
|
this.state = KafkaKRaftState.Leader;
|
|
this.commitIndex = length(this.log);
|
|
}
|
|
|
|
AppendEntries(follower: NodeId) {
|
|
if (!(this.state == KafkaKRaftState.Leader)) throw new Error('Guard failed: this.state == KafkaKRaftState.Leader');
|
|
this.log = append(this.log, newEntry);
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|