hamok
Version:
Lightweight Distributed Object Storage on RAFT consensus algorithm
81 lines (80 loc) • 2.71 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RaftEngine = void 0;
const RaftMessageEmitter_1 = require("../messages/RaftMessageEmitter");
const SyncedProperties_1 = require("./SyncedProperties");
const RaftEmptyState_1 = require("./RaftEmptyState");
const logger_1 = require("../common/logger");
const logger = (0, logger_1.createLogger)('RaftEngine');
class RaftEngine {
config;
logs;
events;
_state;
props = new SyncedProperties_1.SyncedProperties();
_leaderId;
remotePeers = new Set();
transport = new RaftMessageEmitter_1.RaftMessageEmitter();
_failedElections = 0;
constructor(config, logs, events) {
this.config = config;
this.logs = logs;
this.events = events;
if (this.config.heartbeatInMs < 1)
throw new Error('Config error: heartbeatInMs must be greater than 0');
this._state = (0, RaftEmptyState_1.createRaftEmptyState)({
raftEngine: this,
});
}
get localPeerId() {
return this.config.peerId;
}
get leaderId() {
return this._leaderId;
}
get failedElections() {
return this._failedElections;
}
set leaderId(newLeaderId) {
if (this._leaderId === newLeaderId)
return;
const prevLeaderId = this._leaderId;
this._leaderId = newLeaderId;
logger.info(`%s Leader changed from ${prevLeaderId} to ${newLeaderId}`, this.localPeerId);
if (newLeaderId !== undefined) {
this._failedElections = 0;
}
this.events.emit('leader-changed', newLeaderId, prevLeaderId);
}
get state() {
return this._state;
}
set state(newState) {
if (this._state.stateName === newState.stateName)
return;
const prevState = this._state;
prevState.close();
this._state = newState;
logger.debug(`%s State changed from ${prevState.stateName} to ${newState.stateName}`, this.localPeerId);
if (prevState.stateName === 'candidate' && newState.stateName === 'follower') {
++this._failedElections;
}
newState.init?.();
this.events.emit('state-changed', newState.stateName, prevState.stateName);
switch (newState.stateName) {
case 'leader':
case 'follower':
case 'candidate':
this.events.emit(newState.stateName);
break;
}
}
submit(message) {
if (this._state.stateName !== 'leader') {
return false;
}
this.logs.submit(this.props.currentTerm, message);
return true;
}
}
exports.RaftEngine = RaftEngine;