mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-04 14:06:07 +00:00
feat: queue to spawn workers (#255)
* feat: queue to spawn workers * fix: using optional chaining
This commit is contained in:
parent
498c66efdb
commit
633b19c382
@ -16,6 +16,7 @@ import type {
|
|||||||
WorkerSendResultPayload,
|
WorkerSendResultPayload,
|
||||||
WorkerSendShardInfo,
|
WorkerSendShardInfo,
|
||||||
WorkerShardInfo,
|
WorkerShardInfo,
|
||||||
|
WorkerShardsConnected,
|
||||||
WorkerStart,
|
WorkerStart,
|
||||||
} from '../websocket/discord/worker';
|
} from '../websocket/discord/worker';
|
||||||
import type { ManagerMessages } from '../websocket/discord/workermanager';
|
import type { ManagerMessages } from '../websocket/discord/workermanager';
|
||||||
@ -225,6 +226,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
|
|||||||
const onPacket = this.onPacket.bind(this);
|
const onPacket = this.onPacket.bind(this);
|
||||||
const handlePayload = this.options?.handlePayload?.bind(this);
|
const handlePayload = this.options?.handlePayload?.bind(this);
|
||||||
const self = this;
|
const self = this;
|
||||||
|
const { sendPayloadToParent } = this.options;
|
||||||
for (const id of workerData.shards) {
|
for (const id of workerData.shards) {
|
||||||
let shard = this.shards.get(id);
|
let shard = this.shards.get(id);
|
||||||
if (!shard) {
|
if (!shard) {
|
||||||
@ -241,12 +243,13 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
|
|||||||
async handlePayload(shardId, payload) {
|
async handlePayload(shardId, payload) {
|
||||||
await handlePayload?.(shardId, payload);
|
await handlePayload?.(shardId, payload);
|
||||||
await onPacket?.(payload, shardId);
|
await onPacket?.(payload, shardId);
|
||||||
self.postMessage({
|
if (sendPayloadToParent)
|
||||||
workerId: workerData.workerId,
|
self.postMessage({
|
||||||
shardId,
|
workerId: workerData.workerId,
|
||||||
type: 'RECEIVE_PAYLOAD',
|
shardId,
|
||||||
payload,
|
type: 'RECEIVE_PAYLOAD',
|
||||||
} satisfies WorkerReceivePayload);
|
payload,
|
||||||
|
} satisfies WorkerReceivePayload);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.shards.set(id, shard);
|
this.shards.set(id, shard);
|
||||||
@ -418,6 +421,13 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
|
|||||||
this.applicationId = packet.d.application.id;
|
this.applicationId = packet.d.application.id;
|
||||||
this.me = Transformers.ClientUser(this, packet.d.user, packet.d.application) as never;
|
this.me = Transformers.ClientUser(this, packet.d.user, packet.d.application) as never;
|
||||||
await this.events?.execute(packet.t as never, packet, this, shardId);
|
await this.events?.execute(packet.t as never, packet, this, shardId);
|
||||||
|
if ([...this.shards.values()].every(shard => shard.data.session_id)) {
|
||||||
|
this.postMessage({
|
||||||
|
type: 'WORKER_SHARDS_CONNECTED',
|
||||||
|
workerId: this.workerId,
|
||||||
|
} as WorkerShardsConnected);
|
||||||
|
await this.events?.runEvent('WORKER_SHARDS_CONNECTED', this, this.me, -1);
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
!(
|
!(
|
||||||
this.__handleGuilds?.size &&
|
this.__handleGuilds?.size &&
|
||||||
@ -460,4 +470,6 @@ interface WorkerClientOptions extends BaseClientOptions {
|
|||||||
handlePayload?: ShardManagerOptions['handlePayload'];
|
handlePayload?: ShardManagerOptions['handlePayload'];
|
||||||
gateway?: ClientOptions['gateway'];
|
gateway?: ClientOptions['gateway'];
|
||||||
postMessage?: (body: unknown) => unknown;
|
postMessage?: (body: unknown) => unknown;
|
||||||
|
/** can have perfomance issues in big bots if the client sends every event, specially in startup (false by default) */
|
||||||
|
sendPayloadToParent?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -8,3 +8,7 @@ export const BOT_READY = (_self: UsingClient, me: ClientUserStructure) => {
|
|||||||
export const WORKER_READY = (_self: UsingClient, me: ClientUserStructure) => {
|
export const WORKER_READY = (_self: UsingClient, me: ClientUserStructure) => {
|
||||||
return me;
|
return me;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WORKER_SHARDS_CONNECTED = (_self: UsingClient, me: ClientUserStructure) => {
|
||||||
|
return me;
|
||||||
|
};
|
||||||
|
@ -51,6 +51,7 @@ export type WorkerSendCacheRequest = CreateWorkerMessage<
|
|||||||
export type WorkerSendShardInfo = CreateWorkerMessage<'SHARD_INFO', WorkerShardInfo & { nonce: string }>;
|
export type WorkerSendShardInfo = CreateWorkerMessage<'SHARD_INFO', WorkerShardInfo & { nonce: string }>;
|
||||||
export type WorkerSendInfo = CreateWorkerMessage<'WORKER_INFO', WorkerInfo & { nonce: string }>;
|
export type WorkerSendInfo = CreateWorkerMessage<'WORKER_INFO', WorkerInfo & { nonce: string }>;
|
||||||
export type WorkerReady = CreateWorkerMessage<'WORKER_READY'>;
|
export type WorkerReady = CreateWorkerMessage<'WORKER_READY'>;
|
||||||
|
export type WorkerShardsConnected = CreateWorkerMessage<'WORKER_SHARDS_CONNECTED'>;
|
||||||
export type WorkerStart = CreateWorkerMessage<'WORKER_START'>;
|
export type WorkerStart = CreateWorkerMessage<'WORKER_START'>;
|
||||||
export type WorkerSendApiRequest = CreateWorkerMessage<
|
export type WorkerSendApiRequest = CreateWorkerMessage<
|
||||||
'WORKER_API_REQUEST',
|
'WORKER_API_REQUEST',
|
||||||
@ -87,6 +88,7 @@ export type WorkerMessage =
|
|||||||
| WorkerSendShardInfo
|
| WorkerSendShardInfo
|
||||||
| WorkerSendInfo
|
| WorkerSendInfo
|
||||||
| WorkerReady
|
| WorkerReady
|
||||||
|
| WorkerShardsConnected
|
||||||
| WorkerSendApiRequest
|
| WorkerSendApiRequest
|
||||||
| WorkerSendEvalResponse
|
| WorkerSendEvalResponse
|
||||||
| WorkerSendEval
|
| WorkerSendEval
|
||||||
|
@ -18,6 +18,7 @@ export class WorkerManager extends Map<
|
|||||||
options!: MakePartial<Required<WorkerManagerOptions>, 'adapter'>;
|
options!: MakePartial<Required<WorkerManagerOptions>, 'adapter'>;
|
||||||
debugger?: Logger;
|
debugger?: Logger;
|
||||||
connectQueue!: ConnectQueue;
|
connectQueue!: ConnectQueue;
|
||||||
|
workerQueue: (() => void)[] = [];
|
||||||
cacheAdapter: Adapter;
|
cacheAdapter: Adapter;
|
||||||
promises = new Map<string, { resolve: (value: any) => void; timeout: NodeJS.Timeout }>();
|
promises = new Map<string, { resolve: (value: any) => void; timeout: NodeJS.Timeout }>();
|
||||||
rest!: ApiHandler;
|
rest!: ApiHandler;
|
||||||
@ -135,20 +136,22 @@ export class WorkerManager extends Map<
|
|||||||
if (!worker_threads) throw new Error('Cannot prepare workers without worker_threads.');
|
if (!worker_threads) throw new Error('Cannot prepare workers without worker_threads.');
|
||||||
|
|
||||||
for (let i = 0; i < shards.length; i++) {
|
for (let i = 0; i < shards.length; i++) {
|
||||||
let worker = this.get(i);
|
const workerExists = this.has(i);
|
||||||
if (!worker) {
|
if (!workerExists) {
|
||||||
worker = this.createWorker({
|
this.workerQueue.push(() => {
|
||||||
path: this.options.path,
|
const worker = this.createWorker({
|
||||||
debug: this.options.debug,
|
path: this.options.path,
|
||||||
token: this.options.token,
|
debug: this.options.debug,
|
||||||
shards: shards[i],
|
token: this.options.token,
|
||||||
intents: this.options.intents,
|
shards: shards[i],
|
||||||
workerId: i,
|
intents: this.options.intents,
|
||||||
workerProxy: this.options.workerProxy,
|
workerId: i,
|
||||||
totalShards: this.totalShards,
|
workerProxy: this.options.workerProxy,
|
||||||
mode: this.options.mode,
|
totalShards: this.totalShards,
|
||||||
|
mode: this.options.mode,
|
||||||
|
});
|
||||||
|
this.set(i, worker);
|
||||||
});
|
});
|
||||||
this.set(i, worker);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,6 +291,17 @@ export class WorkerManager extends Map<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'WORKER_SHARDS_CONNECTED':
|
||||||
|
{
|
||||||
|
const nextWorker = this.workerQueue.shift();
|
||||||
|
if (nextWorker) {
|
||||||
|
this.debugger?.info('Spawning next worker');
|
||||||
|
nextWorker();
|
||||||
|
} else {
|
||||||
|
this.debugger?.info('No more workers to spawn left');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'WORKER_API_REQUEST':
|
case 'WORKER_API_REQUEST':
|
||||||
{
|
{
|
||||||
const response = await this.rest.request(message.method, message.url, message.requestOptions);
|
const response = await this.rest.request(message.method, message.url, message.requestOptions);
|
||||||
@ -431,6 +445,8 @@ export class WorkerManager extends Map<
|
|||||||
|
|
||||||
const spaces = this.prepareSpaces();
|
const spaces = this.prepareSpaces();
|
||||||
await this.prepareWorkers(spaces);
|
await this.prepareWorkers(spaces);
|
||||||
|
// Start workers queue
|
||||||
|
return this.workerQueue.shift()?.();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user