UNPKG

hamok

Version:

Lightweight Distributed Object Storage on RAFT consensus algorithm

81 lines (80 loc) 2.71 kB
"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;