Skip to content

Commit

Permalink
CJS support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gygi4 committed Sep 18, 2022
1 parent 2969029 commit 7fc9f13
Show file tree
Hide file tree
Showing 18 changed files with 267 additions and 174 deletions.
47 changes: 27 additions & 20 deletions dist/Core/Cluster.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import EventEmitter from 'events';
import path from 'path';
import { delayFor, generateNonce } from '../Util/Util';
import { messageType } from '../types/shared';
import { IPCMessage, BaseMessage } from '../Structures/IPCMessage.js';
import { ClusterHandler } from '../Structures/IPCHandler.js';
import { Worker } from '../Structures/Worker.js';
import { Child } from '../Structures/Child.js';
export class Cluster extends EventEmitter {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cluster = void 0;
const events_1 = __importDefault(require("events"));
const path_1 = __importDefault(require("path"));
const Util_1 = require("../Util/Util");
const shared_1 = require("../types/shared");
const IPCMessage_js_1 = require("../Structures/IPCMessage.js");
const IPCHandler_js_1 = require("../Structures/IPCHandler.js");
const Worker_js_1 = require("../Structures/Worker.js");
const Child_js_1 = require("../Structures/Child.js");
class Cluster extends events_1.default {
THREAD;
manager;
id;
Expand All @@ -21,7 +27,7 @@ export class Cluster extends EventEmitter {
ready;
constructor(manager, id, shardList, totalShards) {
super();
this.THREAD = manager.mode === 'worker' ? Worker : Child;
this.THREAD = manager.mode === 'worker' ? Worker_js_1.Worker : Child_js_1.Child;
this.manager = manager;
this.id = id;
this.args = manager.shardArgs || [];
Expand Down Expand Up @@ -60,14 +66,14 @@ export class Cluster extends EventEmitter {
async spawn(spawnTimeout = 30000) {
if (this.thread)
throw new Error('CLUSTER ALREADY SPAWNED | ClusterId: ' + this.id);
this.thread = new this.THREAD(path.resolve(this.manager.file), {
this.thread = new this.THREAD(path_1.default.resolve(this.manager.file), {
...this.manager.clusterOptions,
execArgv: this.execArgv,
env: this.env,
args: this.args,
clusterData: { ...this.env, ...this.manager.clusterData },
});
this.messageHandler = new ClusterHandler(this.manager, this, this.thread);
this.messageHandler = new IPCHandler_js_1.ClusterHandler(this.manager, this, this.thread);
this.thread
.spawn()
.on('message', this._handleMessage.bind(this))
Expand Down Expand Up @@ -113,32 +119,32 @@ export class Cluster extends EventEmitter {
if (this.thread)
this.kill({ force: true });
if (delay > 0)
await delayFor(delay);
await (0, Util_1.delayFor)(delay);
this.manager.heartbeat?.clusters.get(this.id)?.stop();
return this.spawn(timeout);
}
send(message) {
if (typeof message === 'object')
this.thread?.send(new BaseMessage(message).toJSON());
this.thread?.send(new IPCMessage_js_1.BaseMessage(message).toJSON());
else
return this.thread?.send(message);
}
request(message) {
message._type = messageType.CUSTOM_REQUEST;
message._type = shared_1.messageType.CUSTOM_REQUEST;
this.send(message);
return this.manager.promise.create(message, message.options);
}
async eval(script, context, timeout) {
const _eval = typeof script === 'function' ? `(${script})(this, ${JSON.stringify(context)})` : script;
if (!this.thread)
return Promise.reject(new Error('CLUSTERING_NO_CHILD_EXISTS | ClusterId: ' + this.id));
const nonce = generateNonce();
const message = { nonce, _eval, options: { timeout }, _type: messageType.CLIENT_EVAL_REQUEST };
const nonce = (0, Util_1.generateNonce)();
const message = { nonce, _eval, options: { timeout }, _type: shared_1.messageType.CLIENT_EVAL_REQUEST };
await this.send(message);
return await this.manager.promise.create(message, message.options);
}
triggerMaintenance(reason) {
const _type = reason ? messageType.CLIENT_MAINTENANCE_ENABLE : messageType.CLIENT_MAINTENANCE_DISABLE;
const _type = reason ? shared_1.messageType.CLIENT_MAINTENANCE_ENABLE : shared_1.messageType.CLIENT_MAINTENANCE_DISABLE;
return this.send({ _type, maintenance: reason });
}
_handleMessage(message) {
Expand All @@ -149,8 +155,8 @@ export class Cluster extends EventEmitter {
return;
let emitMessage;
if (typeof message === 'object') {
emitMessage = new IPCMessage(this, message);
if (emitMessage._type === messageType.CUSTOM_REQUEST)
emitMessage = new IPCMessage_js_1.IPCMessage(this, message);
if (emitMessage._type === shared_1.messageType.CUSTOM_REQUEST)
this.manager.emit('clientRequest', emitMessage);
}
else
Expand Down Expand Up @@ -183,3 +189,4 @@ export class Cluster extends EventEmitter {
this.manager.emit('error', error);
}
}
exports.Cluster = Cluster;
63 changes: 35 additions & 28 deletions dist/Core/ClusterClient.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { IPCMessage, BaseMessage } from '../Structures/IPCMessage';
import { Events, messageType, } from '../types/shared';
import { getInfo } from '../Structures/Data';
import { WorkerClient } from '../Structures/Worker';
import { ChildClient } from '../Structures/Child';
import { ClusterClientHandler } from '../Structures/IPCHandler';
import { PromiseHandler } from '../Structures/PromiseHandler';
import EventEmitter from 'events';
import { generateNonce } from '../Util/Util';
export class ClusterClient extends EventEmitter {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClusterClient = void 0;
const IPCMessage_1 = require("../Structures/IPCMessage");
const shared_1 = require("../types/shared");
const Data_1 = require("../Structures/Data");
const Worker_1 = require("../Structures/Worker");
const Child_1 = require("../Structures/Child");
const IPCHandler_1 = require("../Structures/IPCHandler");
const PromiseHandler_1 = require("../Structures/PromiseHandler");
const events_1 = __importDefault(require("events"));
const Util_1 = require("../Util/Util");
class ClusterClient extends events_1.default {
client;
mode;
queue;
Expand All @@ -33,11 +39,11 @@ export class ClusterClient extends EventEmitter {
this.ready = false;
this.process = null;
if (mode === 'process')
this.process = new ChildClient();
this.process = new Child_1.ChildClient();
else if (mode === 'worker')
this.process = new WorkerClient();
this.messageHandler = new ClusterClientHandler(this, this.process);
this.promise = new PromiseHandler();
this.process = new Worker_1.WorkerClient();
this.messageHandler = new IPCHandler_1.ClusterClientHandler(this, this.process);
this.promise = new PromiseHandler_1.PromiseHandler();
this.process?.ipc?.on('message', this._handleMessage.bind(this));
client.on?.('ready', () => {
this.triggerReady();
Expand All @@ -55,19 +61,19 @@ export class ClusterClient extends EventEmitter {
return this.info.CLUSTER_COUNT;
}
get info() {
return getInfo();
return (0, Data_1.getInfo)();
}
send(message) {
if (typeof message === 'object')
message = new BaseMessage(message).toJSON();
message = new IPCMessage_1.BaseMessage(message).toJSON();
return this.process?.send(message);
}
fetchClientValues(prop, cluster) {
return this.broadcastEval(`this.${prop}`, { cluster });
}
async evalOnManager(script, options) {
const evalOptions = options || { _type: undefined };
evalOptions._type = messageType.CLIENT_MANAGER_EVAL_REQUEST;
evalOptions._type = shared_1.messageType.CLIENT_MANAGER_EVAL_REQUEST;
return await this.broadcastEval(script, evalOptions);
}
async broadcastEval(script, options) {
Expand All @@ -76,24 +82,24 @@ export class ClusterClient extends EventEmitter {
const broadcastOptions = options || { context: undefined, _type: undefined, timeout: undefined };
script =
typeof script === 'function' ? `(${script})(this, ${JSON.stringify(broadcastOptions.context)})` : script;
const nonce = generateNonce();
const nonce = (0, Util_1.generateNonce)();
const message = {
nonce,
_eval: script,
options,
_type: broadcastOptions._type || messageType.CLIENT_BROADCAST_REQUEST,
_type: broadcastOptions._type || shared_1.messageType.CLIENT_BROADCAST_REQUEST,
};
await this.send(message);
return await this.promise.create(message, broadcastOptions);
}
request(message) {
const rawMessage = message || { _type: undefined };
rawMessage._type = messageType.CUSTOM_REQUEST;
rawMessage._type = shared_1.messageType.CUSTOM_REQUEST;
this.send(rawMessage);
return this.promise.create(rawMessage, {});
}
respawnAll({ clusterDelay = 5000, respawnDelay = 7000, timeout = 30000 } = {}) {
return this.send({ _type: messageType.CLIENT_RESPAWN_ALL, options: { clusterDelay, respawnDelay, timeout } });
return this.send({ _type: shared_1.messageType.CLIENT_RESPAWN_ALL, options: { clusterDelay, respawnDelay, timeout } });
}
async _handleMessage(message) {
if (!message)
Expand All @@ -103,7 +109,7 @@ export class ClusterClient extends EventEmitter {
return;
let emitMessage;
if (typeof message === 'object')
emitMessage = new IPCMessage(this, message);
emitMessage = new IPCMessage_1.IPCMessage(this, message);
else
emitMessage = message;
this.emit('message', emitMessage);
Expand All @@ -121,31 +127,32 @@ export class ClusterClient extends EventEmitter {
this.send(message)?.catch(err => {
const error = { err, message: '' };
error.message = `Error when sending ${type} response to master process: ${err.message}`;
this.client.emit?.(Events.ERROR, error);
this.client.emit?.(shared_1.Events.ERROR, error);
});
}
triggerReady() {
this.process?.send({ _type: messageType.CLIENT_READY });
this.process?.send({ _type: shared_1.messageType.CLIENT_READY });
this.ready = true;
return this.ready;
}
triggerClusterReady() {
return this.emit('ready', this);
}
triggerMaintenance(maintenance, all = false) {
let _type = messageType.CLIENT_MAINTENANCE;
let _type = shared_1.messageType.CLIENT_MAINTENANCE;
if (all)
_type = messageType.CLIENT_MAINTENANCE_ALL;
_type = shared_1.messageType.CLIENT_MAINTENANCE_ALL;
this.process?.send({ _type, maintenance });
this.maintenance = maintenance;
return this.maintenance;
}
spawnNextCluster() {
if (this.queue.mode === 'auto')
throw new Error('Next Cluster can just be spawned when the queue is not on auto mode.');
return this.process?.send({ _type: messageType.CLIENT_SPAWN_NEXT_CLUSTER });
return this.process?.send({ _type: shared_1.messageType.CLIENT_SPAWN_NEXT_CLUSTER });
}
static getInfo() {
return getInfo();
return (0, Data_1.getInfo)();
}
}
exports.ClusterClient = ClusterClient;
49 changes: 28 additions & 21 deletions dist/Core/ClusterManager.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import fs from 'fs';
import path from 'path';
import os from 'os';
import EventEmitter from 'events';
import { chunkArray, delayFor, fetchRecommendedShards, makePlainError, shardIdForGuildId } from '../Util/Util';
import { Queue } from '../Structures/Queue';
import { Cluster } from './Cluster';
import { PromiseHandler } from '../Structures/PromiseHandler';
export class ClusterManager extends EventEmitter {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClusterManager = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const os_1 = __importDefault(require("os"));
const events_1 = __importDefault(require("events"));
const Util_1 = require("../Util/Util");
const Queue_1 = require("../Structures/Queue");
const Cluster_1 = require("./Cluster");
const PromiseHandler_1 = require("../Structures/PromiseHandler");
class ClusterManager extends events_1.default {
respawn;
restarts;
clusterData;
Expand Down Expand Up @@ -41,9 +47,9 @@ export class ClusterManager extends EventEmitter {
this.file = file;
if (!file)
throw new Error('CLIENT_INVALID_OPTION | No File specified.');
if (!path.isAbsolute(file))
this.file = path.resolve(process.cwd(), file);
const stats = fs.statSync(this.file);
if (!path_1.default.isAbsolute(file))
this.file = path_1.default.resolve(process.cwd(), file);
const stats = fs_1.default.statSync(this.file);
if (!stats.isFile())
throw new Error('CLIENT_INVALID_OPTION | Provided is file is not type of file');
this.totalShards = options.totalShards === 'auto' ? -1 : options.totalShards ?? -1;
Expand Down Expand Up @@ -122,9 +128,9 @@ export class ClusterManager extends EventEmitter {
options.queue = { auto: true };
if (!options.queue.timeout)
options.queue.timeout = this.spawnOptions.delay;
this.queue = new Queue(options.queue);
this.queue = new Queue_1.Queue(options.queue);
this._debug(`[START] Cluster Manager has been initialized`);
this.promise = new PromiseHandler();
this.promise = new PromiseHandler_1.PromiseHandler();
}
async spawn({ amount = this.totalShards, delay, timeout } = this.spawnOptions) {
if (delay < 7000) {
Expand All @@ -135,7 +141,7 @@ export class ClusterManager extends EventEmitter {
if (amount === -1 || amount === 'auto') {
if (!this.token)
throw new Error('A Token must be provided, when totalShards is set on auto.');
amount = await fetchRecommendedShards(this.token, 1000);
amount = await (0, Util_1.fetchRecommendedShards)(this.token, 1000);
this.totalShards = amount;
this._debug(`Discord recommended a total shard count of ${amount}`);
}
Expand All @@ -151,7 +157,7 @@ export class ClusterManager extends EventEmitter {
}
let clusterAmount = this.totalClusters;
if (clusterAmount === -1) {
clusterAmount = os.cpus().length;
clusterAmount = os_1.default.cpus().length;
this.totalClusters = clusterAmount;
}
else {
Expand All @@ -168,7 +174,7 @@ export class ClusterManager extends EventEmitter {
this.shardList = Array.from(Array(amount).keys());
if (this.shardsPerClusters)
this.totalClusters = Math.ceil(this.shardList.length / this.shardsPerClusters);
this.shardClusterList = chunkArray(this.shardList, Math.ceil(this.shardList.length / this.totalClusters));
this.shardClusterList = (0, Util_1.chunkArray)(this.shardList, Math.ceil(this.shardList.length / this.totalClusters));
if (this.shardClusterList.length !== this.totalClusters) {
this.totalClusters = this.shardClusterList.length;
}
Expand Down Expand Up @@ -204,7 +210,7 @@ export class ClusterManager extends EventEmitter {
return Promise.all(promises);
}
createCluster(id, shardsToSpawn, totalShards, recluster = false) {
const cluster = new Cluster(this, id, shardsToSpawn, totalShards);
const cluster = new Cluster_1.Cluster(this, id, shardsToSpawn, totalShards);
if (!recluster)
this.clusters.set(id, cluster);
this.emit('clusterCreate', cluster);
Expand All @@ -227,7 +233,7 @@ export class ClusterManager extends EventEmitter {
}
}
if (options.guildId) {
options.shard = shardIdForGuildId(options.guildId, this.totalShards);
options.shard = (0, Util_1.shardIdForGuildId)(options.guildId, this.totalShards);
}
if (options.shard) {
if (typeof options.shard === 'number') {
Expand Down Expand Up @@ -273,7 +279,7 @@ export class ClusterManager extends EventEmitter {
const promises = [cluster.respawn({ delay: respawnDelay, timeout })];
const length = this.shardClusterList[i]?.length || this.totalShards / this.totalClusters;
if (++s < this.clusters.size && clusterDelay > 0)
promises.push(delayFor(length * clusterDelay));
promises.push((0, Util_1.delayFor)(length * clusterDelay));
i++;
await Promise.all(promises);
}
Expand All @@ -290,7 +296,7 @@ export class ClusterManager extends EventEmitter {
catch (err) {
error = err;
}
return { _result: result, _error: error ? makePlainError(error) : null };
return { _result: result, _error: error ? (0, Util_1.makePlainError)(error) : null };
}
evalOnCluster(script, options) {
return this.broadcastEval(script, options)?.then((r) => r[0]);
Expand Down Expand Up @@ -323,3 +329,4 @@ export class ClusterManager extends EventEmitter {
return log;
}
}
exports.ClusterManager = ClusterManager;
Loading

0 comments on commit 7fc9f13

Please sign in to comment.