Skip to content
This repository was archived by the owner on Apr 17, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion libs/common/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export const CORDIS_META: {
} = {
url: pkg.homepage.split('#')[0],
version: pkg.version
};
} as const;

Object.freeze(CORDIS_META);

/**
* Root endpoints for Discord
Expand All @@ -28,3 +30,44 @@ export const ENDPOINTS = {
} as const;

Object.freeze(ENDPOINTS);

/**
* Interface representing configuration for the gateway service
*/
export interface GatewayServiceConfig {
auth: string;
amqpHost: string;
debug: boolean;
shardCount: number | 'auto';
startingShard: number;
totalShardCount: number | 'auto';
ws: {
compress: boolean;
encoding: 'json' | 'etf';
timeouts: {
open: number;
hello: number;
ready: number;
guild: number;
reconnect: number;
};
largeThreshold: number;
intents: string[];
};
}

/**
* Injection tokens used by the gateway service
*/
export const GATEWAY_INJECTION_TOKENS = {
kConfig: Symbol('parsed configuration options'),
amqp: {
kChannel: Symbol('amqp channel object'),
kConnection: Symbol('amqp connection object'),
kService: Symbol('RoutingServer instance for distributing the incoming packets'),
kCommandsServer: Symbol('"server" recieving payloads (called commands) to send to Discord')
},
kCluster: Symbol('Cluster instance')
} as const;

Object.freeze(GATEWAY_INJECTION_TOKENS);
29 changes: 16 additions & 13 deletions pnpm-lock.yaml

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

2 changes: 2 additions & 0 deletions services/gateway/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
"@cordis/common": "workspace:^0.1.7",
"@cordis/gateway": "workspace:^0.1.7",
"erlpack": "github:discord/erlpack",
"reflect-metadata": "^0.1.13",
"tslib": "^2.1.0",
"tsyringe": "^4.4.0",
"yargs": "^15.4.1",
"zlib-sync": "^0.1.7"
}
Expand Down
56 changes: 48 additions & 8 deletions services/gateway/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import 'reflect-metadata';
import { container } from 'tsyringe';
import * as yargs from 'yargs';
import { createAmqp, RoutingServer, PubSubClient } from '@cordis/brokers';
import { Cluster, IntentKeys } from '@cordis/gateway';
import type { DiscordEvents } from '@cordis/common';
import { DiscordEvents, GatewayServiceConfig, GATEWAY_INJECTION_TOKENS } from '@cordis/common';
import type { GatewaySendPayload } from 'discord-api-types/v8';

const loadExtension = async (name: string) => {
try {
await require(`../extensions/${name}`);
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') console.error(`[${name.toUpperCase()} EXTENSION ERROR]`, e);
}
};

const main = async () => {
const { argv } = yargs
.env('CORDIS')
Expand Down Expand Up @@ -45,12 +55,6 @@ const main = async () => {
'demandOption': false,
'default': 'auto' as const
})
.option('redis-url', {
global: true,
description: 'URL for connecting to your redis instance',
type: 'string',
demandOption: false
})
.option('ws-compress', {
'global': true,
'description': 'Whether or not to use compression',
Expand All @@ -61,7 +65,7 @@ const main = async () => {
'global': true,
'description': 'What websocket encoding to use, JSON or ETF',
'type': 'string',
'default': 'etf'
'default': 'etf' as const
})
.option('ws-open-timeout', {
'global': true,
Expand Down Expand Up @@ -115,6 +119,32 @@ const main = async () => {
})
.help();

const config: GatewayServiceConfig = {
auth: argv.auth,
amqpHost: argv['amqp-host'],
debug: argv.debug,
shardCount: argv['shard-count'],
startingShard: argv['starting-shard'],
totalShardCount: argv['total-shard-count'],
ws: {
compress: argv['ws-compress'],
encoding: argv['ws-encoding'],
timeouts: {
open: argv['ws-open-timeout'],
hello: argv['ws-hello-timeout'],
ready: argv['ws-ready-timeout'],
guild: argv['ws-guild-timeout'],
reconnect: argv['ws-reconnect-timeout']
},
largeThreshold: argv['ws-large-threshold'],
intents: argv['ws-intents']
}
};

container.register(GATEWAY_INJECTION_TOKENS.kConfig, { useValue: config });

await loadExtension('pre-setup');

const { channel, connection } = await createAmqp(argv['amqp-host']);
connection
.on('error', e => console.error(`[AMQP ERROR]: ${e}`))
Expand Down Expand Up @@ -149,6 +179,12 @@ const main = async () => {
cb: req => cluster.broadcast(req)
});

container.register(GATEWAY_INJECTION_TOKENS.amqp.kChannel, { useValue: channel });
container.register(GATEWAY_INJECTION_TOKENS.amqp.kConnection, { useValue: connection });
container.register(GATEWAY_INJECTION_TOKENS.amqp.kService, { useValue: service });
container.register(GATEWAY_INJECTION_TOKENS.amqp.kCommandsServer, { useValue: gatewayCommandsServer });
container.register(GATEWAY_INJECTION_TOKENS.kCluster, { useValue: cluster });

cluster
.on('disconnecting', id => console.log(`[DISCONNECTING]: Shard id ${id}`))
.on('reconnecting', id => console.log(`[RECONNECTING]: Shard id ${id}`))
Expand All @@ -157,11 +193,15 @@ const main = async () => {
.on('ready', () => console.log('[READY]: All shards have fully connected'))
.on('dispatch', data => service.publish(data.t, data.d));

await loadExtension('pre-init');

if (argv.debug) cluster.on('debug', (info, id) => console.log(`[DEBUG]: Shard id ${id}`, info));

try {
await service.init({ name: 'gateway', topicBased: false });
await cluster.connect();

await loadExtension('post-init');
} catch (e) {
console.error('Failed to initialize the service or the cluster', e);
process.exit(1);
Expand Down