mirror of
https://github.com/discordeno/discordeno.git
synced 2026-09-17 08:47:22 +00:00
example(bigbot): Spawn one shard at a time (#4127)
* Spawn one shard at a time * remove useless code in ShardIdentified handling * update comment on tellWorkerToIdentify * fix mistake * Use request identify This also makes some unrelated changes needed to make the example comple when using the build from this branch. * remove debug logs
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Collection, LogDepth, createBot, type logger } from '@discordeno/bot'
|
import { Collection, createBot } from '@discordeno/bot'
|
||||||
import { DISCORD_TOKEN, GATEWAY_AUTHORIZATION, GATEWAY_INTENTS, GATEWAY_URL, REST_AUTHORIZATION, REST_URL } from '../config.js'
|
import { DISCORD_TOKEN, GATEWAY_AUTHORIZATION, GATEWAY_INTENTS, GATEWAY_URL, REST_AUTHORIZATION, REST_URL } from '../config.js'
|
||||||
import type { ManagerGetShardInfoFromGuildId, ShardInfo, WorkerPresencesUpdate, WorkerShardPayload } from '../gateway/worker/types.js'
|
import type { ManagerGetShardInfoFromGuildId, ShardInfo, WorkerPresencesUpdate, WorkerShardPayload } from '../gateway/worker/types.js'
|
||||||
import type { Command } from './commands.js'
|
import type { Command } from './commands.js'
|
||||||
@@ -33,8 +33,6 @@ const rawBot = createBot({
|
|||||||
export const bot = rawBot as CustomBot
|
export const bot = rawBot as CustomBot
|
||||||
|
|
||||||
// TEMPLATE-SETUP: If you want/need to add any custom properties on the Bot type, you can do it in these lines below and the `CustomBot` type below. Make sure to do it in both or else you will get an error by TypeScript
|
// TEMPLATE-SETUP: If you want/need to add any custom properties on the Bot type, you can do it in these lines below and the `CustomBot` type below. Make sure to do it in both or else you will get an error by TypeScript
|
||||||
// We need to set the log depth for the default discordeno logger or else only the first param will be logged
|
|
||||||
;(bot.logger as typeof logger).setDepth(LogDepth.Full)
|
|
||||||
|
|
||||||
bot.commands = new Collection()
|
bot.commands = new Collection()
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import type { Worker } from 'node:worker_threads'
|
import type { Worker } from 'node:worker_threads'
|
||||||
import { LogDepth, createGatewayManager, createLogger, createRestManager } from '@discordeno/bot'
|
import { createGatewayManager, createLogger, createRestManager } from '@discordeno/bot'
|
||||||
import { DISCORD_TOKEN, GATEWAY_INTENTS, REST_AUTHORIZATION, REST_URL, SHARDS_PER_WORKER, TOTAL_SHARDS, TOTAL_WORKERS } from '../config.js'
|
import { DISCORD_TOKEN, GATEWAY_INTENTS, REST_AUTHORIZATION, REST_URL, SHARDS_PER_WORKER, TOTAL_SHARDS, TOTAL_WORKERS } from '../config.js'
|
||||||
|
import { promiseWithResolvers } from '../util.js'
|
||||||
import { createWorker } from './worker/createWorker.js'
|
import { createWorker } from './worker/createWorker.js'
|
||||||
import type { WorkerMessage } from './worker/types.js'
|
import type { ManagerMessage, WorkerMessage } from './worker/types.js'
|
||||||
|
|
||||||
export const workers = new Map<number, Worker>()
|
export const workers = new Map<number, Worker>()
|
||||||
export const logger = createLogger({ name: 'GATEWAY' })
|
export const logger = createLogger({ name: 'GATEWAY' })
|
||||||
logger.setDepth(LogDepth.Full)
|
|
||||||
|
|
||||||
const restManager = createRestManager({
|
const restManager = createRestManager({
|
||||||
token: DISCORD_TOKEN,
|
token: DISCORD_TOKEN,
|
||||||
@@ -37,6 +37,20 @@ gatewayManager.tellWorkerToIdentify = async (workerId, shardId, bucketId) => {
|
|||||||
type: 'IdentifyShard',
|
type: 'IdentifyShard',
|
||||||
shardId,
|
shardId,
|
||||||
} satisfies WorkerMessage)
|
} satisfies WorkerMessage)
|
||||||
|
|
||||||
|
const { promise, resolve } = promiseWithResolvers<void>()
|
||||||
|
|
||||||
|
const waitForShardIdentified = (message: ManagerMessage) => {
|
||||||
|
if (message.type === 'ShardIdentified' && message.shardId === shardId) {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.on('message', waitForShardIdentified)
|
||||||
|
|
||||||
|
await promise
|
||||||
|
|
||||||
|
worker.off('message', waitForShardIdentified)
|
||||||
}
|
}
|
||||||
|
|
||||||
gatewayManager.sendPayload = async (shardId, payload) => {
|
gatewayManager.sendPayload = async (shardId, payload) => {
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ export function createWorker(workerId: number): Worker {
|
|||||||
shardInfoRequests.delete(message.nonce)
|
shardInfoRequests.delete(message.nonce)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (message.type === 'ShardIdentified') {
|
||||||
|
logger.info(`Shard #${message.shardId} identified`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
logger.warn(`Worker - Received unknown message type: ${(message as { type: string }).type}`)
|
logger.warn(`Worker - Received unknown message type: ${(message as { type: string }).type}`)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { ShardSocketRequest, StatusUpdate } from '@discordeno/bot'
|
import type { DiscordUpdatePresence, ShardSocketRequest } from '@discordeno/bot'
|
||||||
|
|
||||||
export type ManagerMessage = ManagerRequestIdentify | ManagerShardInfo
|
export type ManagerMessage = ManagerRequestIdentify | ManagerShardIdentified | ManagerShardInfo
|
||||||
export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerPresencesUpdate | WorkerShardInfo
|
export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerPresencesUpdate | WorkerShardInfo
|
||||||
|
|
||||||
export interface WorkerIdentifyShard {
|
export interface WorkerIdentifyShard {
|
||||||
@@ -26,7 +26,7 @@ export interface WorkerShardPayload {
|
|||||||
|
|
||||||
export interface WorkerPresencesUpdate {
|
export interface WorkerPresencesUpdate {
|
||||||
type: 'EditShardsPresence'
|
type: 'EditShardsPresence'
|
||||||
payload: StatusUpdate
|
payload: DiscordUpdatePresence
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkerShardInfo {
|
export interface WorkerShardInfo {
|
||||||
@@ -71,3 +71,8 @@ export interface ManagerGetShardInfoFromGuildId {
|
|||||||
type: 'ShardInfoFromGuild'
|
type: 'ShardInfoFromGuild'
|
||||||
guildId: string | undefined
|
guildId: string | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ManagerShardIdentified {
|
||||||
|
type: 'ShardIdentified'
|
||||||
|
shardId: number
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import assert from 'node:assert'
|
import assert from 'node:assert'
|
||||||
import { createHash } from 'node:crypto'
|
import { createHash } from 'node:crypto'
|
||||||
import { workerData as _workerData, parentPort } from 'node:worker_threads'
|
import { workerData as _workerData, parentPort } from 'node:worker_threads'
|
||||||
import { DiscordenoShard, GatewayOpcodes, LogDepth, createLogger } from '@discordeno/bot'
|
import { DiscordenoShard, GatewayOpcodes, createLogger } from '@discordeno/bot'
|
||||||
import { type Channel as amqpChannel, connect as connectAmqp } from 'amqplib'
|
import { type Channel as amqpChannel, connect as connectAmqp } from 'amqplib'
|
||||||
import { promiseWithResolvers } from '../../util.js'
|
import { promiseWithResolvers } from '../../util.js'
|
||||||
import type { ManagerMessage, WorkerCreateData, WorkerMessage } from './types.js'
|
import type { ManagerMessage, WorkerCreateData, WorkerMessage } from './types.js'
|
||||||
@@ -11,7 +11,6 @@ assert(parentPort)
|
|||||||
const workerData: WorkerCreateData = _workerData
|
const workerData: WorkerCreateData = _workerData
|
||||||
|
|
||||||
const logger = createLogger({ name: `Worker #${workerData.workerId}` })
|
const logger = createLogger({ name: `Worker #${workerData.workerId}` })
|
||||||
logger.setDepth(LogDepth.Full)
|
|
||||||
|
|
||||||
const identifyPromises = new Map<number, () => void>()
|
const identifyPromises = new Map<number, () => void>()
|
||||||
const shards = new Map<number, DiscordenoShard>()
|
const shards = new Map<number, DiscordenoShard>()
|
||||||
@@ -23,6 +22,8 @@ if (workerData.messageQueue.enabled) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parentPort.on('message', async (message: WorkerMessage) => {
|
parentPort.on('message', async (message: WorkerMessage) => {
|
||||||
|
assert(parentPort)
|
||||||
|
|
||||||
if (message.type === 'IdentifyShard') {
|
if (message.type === 'IdentifyShard') {
|
||||||
logger.info(`Starting to identify shard #${message.shardId}`)
|
logger.info(`Starting to identify shard #${message.shardId}`)
|
||||||
const shard = shards.get(message.shardId) ?? createShard(message.shardId)
|
const shard = shards.get(message.shardId) ?? createShard(message.shardId)
|
||||||
@@ -30,6 +31,11 @@ parentPort.on('message', async (message: WorkerMessage) => {
|
|||||||
|
|
||||||
await shard.identify()
|
await shard.identify()
|
||||||
|
|
||||||
|
parentPort.postMessage({
|
||||||
|
type: 'ShardIdentified',
|
||||||
|
shardId: message.shardId,
|
||||||
|
} satisfies ManagerMessage)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (message.type === 'AllowIdentify') {
|
if (message.type === 'AllowIdentify') {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { LogDepth, createLogger, createRestManager } from '@discordeno/bot'
|
import { createLogger, createRestManager } from '@discordeno/bot'
|
||||||
import { DISCORD_TOKEN } from '../config.js'
|
import { DISCORD_TOKEN } from '../config.js'
|
||||||
import { setupRestAnalyticsHooks } from './influx.js'
|
import { setupRestAnalyticsHooks } from './influx.js'
|
||||||
|
|
||||||
@@ -7,7 +7,6 @@ const manager = createRestManager({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const logger = createLogger({ name: 'REST' })
|
export const logger = createLogger({ name: 'REST' })
|
||||||
logger.setDepth(LogDepth.Full)
|
|
||||||
|
|
||||||
setupRestAnalyticsHooks(manager, logger)
|
setupRestAnalyticsHooks(manager, logger)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user