Skip to content

Commit

Permalink
Merge pull request meister03#67 from Gygi4/ts-rewrite
Browse files Browse the repository at this point in the history
Don't remove comments.
  • Loading branch information
meister03 committed Sep 22, 2022
2 parents 9a420f5 + 8d1984f commit 921a015
Show file tree
Hide file tree
Showing 28 changed files with 740 additions and 16 deletions.
94 changes: 94 additions & 0 deletions dist/Core/Cluster.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,41 @@ import { ClusterEvents, ClusterKillOptions } from '../types/shared';
import { RawMessage } from '../Structures/IPCMessage.js';
import { Worker } from '../Structures/Worker.js';
import { Child } from '../Structures/Child.js';
/**
* A self-contained cluster created by the {@link ClusterManager}. Each one has a {@link Child} that contains
* an instance of the bot and its {@link Client}. When its child process/worker exits for any reason, the cluster will
* spawn a new one to replace it as necessary.
* @augments EventEmitter
*/
export declare class Cluster extends EventEmitter {
THREAD: typeof Worker | typeof Child;
/**
* Manager that created the cluster
*/
manager: ClusterManager;
/**
* ID of the cluster in the manager
*/
id: number;
/**
* Arguments for the shard's process (only when {@link ShardingManager#mode} is `process`)
*/
args: string[];
/**
* Arguments for the shard's process executable (only when {@link ShardingManager#mode} is `process`)
*/
execArgv: string[];
/**
* Internal Shards which will get spawned in the cluster
*/
shardList: number[];
/**
* the amount of real shards
*/
totalShards: number;
/**
* Environment variables for the cluster's process, or workerData for the cluster's worker
*/
env: NodeJS.ProcessEnv & {
SHARD_LIST: number[];
TOTAL_SHARDS: number;
Expand All @@ -24,6 +51,9 @@ export declare class Cluster extends EventEmitter {
CLUSTER_COUNT: number;
DISCORD_TOKEN: string;
};
/**
* Process of the cluster (if {@link ClusterManager#mode} is `process`)
*/
thread: null | Worker | Child;
restarts: {
current: number;
Expand All @@ -35,17 +65,81 @@ export declare class Cluster extends EventEmitter {
append: () => void;
};
messageHandler: any;
/**
* Whether the cluster's {@link Client} is ready
*/
ready: boolean;
/**
* @param manager Manager that is creating this cluster
* @param id ID of this cluster
* @param shardList
* @param totalShards
*/
constructor(manager: ClusterManager, id: number, shardList: number[], totalShards: number);
/**
* Forks a child process or creates a worker thread for the cluster.
* <warn>You should not need to call this manually.</warn>
* @param spawnTimeout The amount in milliseconds to wait until the {@link Client} has become ready
* before resolving. (-1 or Infinity for no wait)
*/
spawn(spawnTimeout?: number): Promise<import("worker_threads").Worker | import("child_process").ChildProcess | null>;
/**
* Immediately kills the clusters process/worker and does not restart it.
* @param options Some Options for managing the Kill
* @param options.force Whether the Cluster should be force kill and be ever respawned...
*/
kill(options: ClusterKillOptions): void;
/**
* Kills and restarts the cluster's process/worker.
* @param options Options for respawning the cluster
*/
respawn({ delay, timeout }?: import("../types/shared").ClusterManagerSpawnOptions): Promise<import("worker_threads").Worker | import("child_process").ChildProcess | null>;
/**
* Sends a message to the cluster's process/worker.
* @param message Message to send to the cluster
*/
send(message: RawMessage): Promise<unknown> | undefined;
/**
* Sends a Request to the ClusterClient and returns the reply
* @param message Message, which should be sent as request
* @returns Reply of the Message
* @example
* client.cluster.request({content: 'hello'})
* .then(result => console.log(result)) //hi
* .catch(console.error);
* @see {@link IPCMessage#reply}
*/
request(message: RawMessage): Promise<unknown>;
/**
* Evaluates a script or function on the cluster, in the context of the {@link Client}.
* @param script JavaScript to run on the cluster
* @param context
* @param timeout
* @returns Result of the script execution
*/
eval(script: string, context: any, timeout: number): Promise<unknown>;
/**
* @param reason If maintenance should be enabled with a given reason or disabled when nonce provided
*/
triggerMaintenance(reason?: string): Promise<unknown> | undefined;
/**
* Handles a message received from the child process/worker.
* @param message Message received
* @private
*/
private _handleMessage;
/**
* Handles the cluster's process/worker exiting.
* @param respawn=this.manager.respawn Whether to spawn the cluster again
* @param {handleExitOptions} options
* @private
*/
private _handleExit;
/**
* Handles the cluster's process/worker error.
* @param error the error, which occurred on the worker/child process
* @private
*/
private _handleError;
}
export interface Cluster {
Expand Down
2 changes: 1 addition & 1 deletion dist/Core/Cluster.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

116 changes: 116 additions & 0 deletions dist/Core/Cluster.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,58 @@ 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");
/**
* A self-contained cluster created by the {@link ClusterManager}. Each one has a {@link Child} that contains
* an instance of the bot and its {@link Client}. When its child process/worker exits for any reason, the cluster will
* spawn a new one to replace it as necessary.
* @augments EventEmitter
*/
class Cluster extends events_1.default {
THREAD;
/**
* Manager that created the cluster
*/
manager;
/**
* ID of the cluster in the manager
*/
id;
/**
* Arguments for the shard's process (only when {@link ShardingManager#mode} is `process`)
*/
args;
/**
* Arguments for the shard's process executable (only when {@link ShardingManager#mode} is `process`)
*/
execArgv;
/**
* Internal Shards which will get spawned in the cluster
*/
shardList;
/**
* the amount of real shards
*/
totalShards;
/**
* Environment variables for the cluster's process, or workerData for the cluster's worker
*/
env;
/**
* Process of the cluster (if {@link ClusterManager#mode} is `process`)
*/
thread;
restarts;
messageHandler;
/**
* Whether the cluster's {@link Client} is ready
*/
ready;
/**
* @param manager Manager that is creating this cluster
* @param id ID of this cluster
* @param shardList
* @param totalShards
*/
constructor(manager, id, shardList, totalShards) {
super();
this.THREAD = manager.mode === 'worker' ? Worker_js_1.Worker : Child_js_1.Child;
Expand Down Expand Up @@ -63,6 +102,12 @@ class Cluster extends events_1.default {
},
};
}
/**
* Forks a child process or creates a worker thread for the cluster.
* <warn>You should not need to call this manually.</warn>
* @param spawnTimeout The amount in milliseconds to wait until the {@link Client} has become ready
* before resolving. (-1 or Infinity for no wait)
*/
async spawn(spawnTimeout = 30000) {
if (this.thread)
throw new Error('CLUSTER ALREADY SPAWNED | ClusterId: ' + this.id);
Expand All @@ -79,6 +124,11 @@ class Cluster extends events_1.default {
.on('message', this._handleMessage.bind(this))
.on('exit', this._handleExit.bind(this))
.on('error', this._handleError.bind(this));
/**
* Emitted upon the creation of the cluster's child process/worker.
* @event Cluster#spawn
* @param {Child|Worker} process Child process/worker that was created
*/
this.emit('spawn', this.thread.process);
if (spawnTimeout === -1 || spawnTimeout === Infinity)
return this.thread.process;
Expand Down Expand Up @@ -109,12 +159,21 @@ class Cluster extends events_1.default {
});
return this.thread.process;
}
/**
* Immediately kills the clusters process/worker and does not restart it.
* @param options Some Options for managing the Kill
* @param options.force Whether the Cluster should be force kill and be ever respawned...
*/
kill(options) {
this.thread?.kill();
this.manager.heartbeat?.clusters.get(this.id)?.stop();
this.restarts.cleanup();
this._handleExit(false, options);
}
/**
* Kills and restarts the cluster's process/worker.
* @param options Options for respawning the cluster
*/
async respawn({ delay = 500, timeout = 30000 } = this.manager.spawnOptions) {
if (this.thread)
this.kill({ force: true });
Expand All @@ -123,30 +182,61 @@ class Cluster extends events_1.default {
this.manager.heartbeat?.clusters.get(this.id)?.stop();
return this.spawn(timeout);
}
/**
* Sends a message to the cluster's process/worker.
* @param message Message to send to the cluster
*/
send(message) {
if (typeof message === 'object')
this.thread?.send(new IPCMessage_js_1.BaseMessage(message).toJSON());
else
return this.thread?.send(message);
}
/**
* Sends a Request to the ClusterClient and returns the reply
* @param message Message, which should be sent as request
* @returns Reply of the Message
* @example
* client.cluster.request({content: 'hello'})
* .then(result => console.log(result)) //hi
* .catch(console.error);
* @see {@link IPCMessage#reply}
*/
request(message) {
message._type = shared_1.messageType.CUSTOM_REQUEST;
this.send(message);
return this.manager.promise.create(message, message.options);
}
/**
* Evaluates a script or function on the cluster, in the context of the {@link Client}.
* @param script JavaScript to run on the cluster
* @param context
* @param timeout
* @returns Result of the script execution
*/
async eval(script, context, timeout) {
// Stringify the script if it's a Function
const _eval = typeof script === 'function' ? `(${script})(this, ${JSON.stringify(context)})` : script;
// cluster is dead (maybe respawning), don't cache anything and error immediately
if (!this.thread)
return Promise.reject(new Error('CLUSTERING_NO_CHILD_EXISTS | ClusterId: ' + this.id));
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);
}
/**
* @param reason If maintenance should be enabled with a given reason or disabled when nonce provided
*/
triggerMaintenance(reason) {
const _type = reason ? shared_1.messageType.CLIENT_MAINTENANCE_ENABLE : shared_1.messageType.CLIENT_MAINTENANCE_DISABLE;
return this.send({ _type, maintenance: reason });
}
/**
* Handles a message received from the child process/worker.
* @param message Message received
* @private
*/
_handleMessage(message) {
if (!message)
return;
Expand All @@ -161,9 +251,25 @@ class Cluster extends events_1.default {
}
else
emitMessage = message;
/**
* Emitted upon receiving a message from the child process/worker.
* @event Shard#message
* @param {*|IPCMessage} message Message that was received
*/
this.emit('message', emitMessage);
}
/**
* Handles the cluster's process/worker exiting.
* @param respawn=this.manager.respawn Whether to spawn the cluster again
* @param {handleExitOptions} options
* @private
*/
_handleExit(respawn = this.manager.respawn, options) {
/**
* Emitted upon the cluster's child process/worker exiting.
* @event Cluster#death
* @param {Child|Worker} process Child process/worker that exited
*/
if (!options)
options = {};
if (options?.reason !== 'reclustering')
Expand All @@ -185,7 +291,17 @@ class Cluster extends events_1.default {
this.spawn().catch(err => this.emit('error', err));
this.restarts.append();
}
/**
* Handles the cluster's process/worker error.
* @param error the error, which occurred on the worker/child process
* @private
*/
_handleError(error) {
/**
* Emitted upon the cluster's child process/worker error.
* @event Cluster#error
* @param {Child|Worker} process Child process/worker, where error occurred
*/
this.manager.emit('error', error);
}
}
Expand Down
Loading

0 comments on commit 921a015

Please sign in to comment.