'use strict'; const debug = require('debug')('cluster-client'); const Base = require('./base'); const Leader = require('../leader'); const Follower = require('../follower'); const ClusterServer = require('../server'); // Symbol const { init, logger, isReady, innerClient, createClient, closeHandler, } = require('../symbol'); class ClusterClient extends Base { constructor(options) { super(options); this[closeHandler] = () => { this[logger].warn('[ClusterClient:%s] %s closed, and try to init it again', this.options.name, this[innerClient].isLeader ? 'leader' : 'follower'); this[isReady] = false; this.ready(false); this[init]().catch(err => { this.ready(err); }); }; } async [createClient]() { const name = this.options.name; const port = this.options.port; let server; if (this.options.isLeader === true) { server = await ClusterServer.create(name, port); if (!server) { throw new Error(`create "${name}" leader failed, the port:${port} is occupied by other`); } } else if (this.options.isLeader === false) { // wait for leader active await ClusterServer.waitFor(port, this.options.maxWaitTime); } else { debug('[ClusterClient:%s] init cluster client, try to seize the leader on port:%d', name, port); server = await ClusterServer.create(name, port); } if (server) { debug('[ClusterClient:%s] has seized port %d, and serves as leader client.', name, port); return new Leader(Object.assign({ server }, this.options)); } debug('[ClusterClient:%s] gives up seizing port %d, and serves as follower client.', name, port); return new Follower(this.options); } } module.exports = ClusterClient;