summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-03-13 10:14:29 +0100
committerRory& <root@rory.gay>2026-03-13 10:14:29 +0100
commit1e07c1eaa28815bc0a385c4faf2b95f1405c1c6c (patch)
tree6e0298c366c9993c68f8a52302414f67e9355c19
parentidentify: use proto toVoiceState (diff)
downloadserver-ts-1e07c1eaa28815bc0a385c4faf2b95f1405c1c6c.tar.xz
gateway offload work
-rw-r--r--extra/admin-api/Spacebar.GatewayOffload/Controllers/ChannelStatusController.cs4
-rw-r--r--extra/admin-api/Spacebar.GatewayOffload/Controllers/Op8Controller.cs2
-rw-r--r--nix/modules/default/cs/gateway-offload-cs.nix14
-rw-r--r--nix/testVm/configuration.nix5
-rw-r--r--src/gateway/opcodes/GuildSync.ts8
-rw-r--r--src/gateway/opcodes/RequestChannelInfo.ts8
-rw-r--r--src/gateway/opcodes/RequestChannelStatuses.ts7
-rw-r--r--src/gateway/opcodes/RequestGuildMembers.ts8
-rw-r--r--src/gateway/util/Utils.ts1
-rw-r--r--src/util/config/types/OffloadConfiguration.ts7
-rw-r--r--src/util/util/Decorators.ts2
11 files changed, 50 insertions, 16 deletions
diff --git a/extra/admin-api/Spacebar.GatewayOffload/Controllers/ChannelStatusController.cs b/extra/admin-api/Spacebar.GatewayOffload/Controllers/ChannelStatusController.cs

index 767e838b..0843218e 100644 --- a/extra/admin-api/Spacebar.GatewayOffload/Controllers/ChannelStatusController.cs +++ b/extra/admin-api/Spacebar.GatewayOffload/Controllers/ChannelStatusController.cs
@@ -15,7 +15,7 @@ namespace Spacebar.GatewayOffload.Controllers; [Route("/_spacebar/offload/gateway")] public class ChannelStatusController(ILogger<ChannelStatusController> logger, SpacebarAspNetAuthenticationService authService, SpacebarDbContext db, IServiceProvider sp) : ControllerBase { - [HttpPost("channelStatuses")] + [HttpPost("ChannelStatuses")] public async IAsyncEnumerable<ReplicationMessage<ChannelStatusesResponse>> GetChannelStatuses([FromBody] ChannelStatusesRequest req) { await foreach (var res in GetChannelInfos(new() { Fields = ["status"], @@ -33,7 +33,7 @@ public class ChannelStatusController(ILogger<ChannelStatusController> logger, Sp } } - [HttpPost("channelInfo")] + [HttpPost("ChannelInfo")] public async IAsyncEnumerable<ReplicationMessage<ChannelInfoResponse>> GetChannelInfos([FromBody] ChannelInfoRequest req) { var user = await authService.GetCurrentUserAsync(Request); string[] statusOptions = [ diff --git a/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op8Controller.cs b/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op8Controller.cs
index dbcd4452..ac68bb22 100644 --- a/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op8Controller.cs +++ b/extra/admin-api/Spacebar.GatewayOffload/Controllers/Op8Controller.cs
@@ -16,7 +16,7 @@ using Spacebar.Models.Generic; namespace Spacebar.GatewayOffload.Controllers; [ApiController] -[Route("/_spacebar/offload/gateway/GuildSync")] +[Route("/_spacebar/offload/gateway/GuildMembers")] public class Op8Controller(ILogger<Op8Controller> logger, SpacebarAspNetAuthenticationService authService, SpacebarDbContext db, IServiceProvider sp) : ControllerBase { [HttpPost("")] diff --git a/nix/modules/default/cs/gateway-offload-cs.nix b/nix/modules/default/cs/gateway-offload-cs.nix
index ebbc1425..6187f075 100644 --- a/nix/modules/default/cs/gateway-offload-cs.nix +++ b/nix/modules/default/cs/gateway-offload-cs.nix
@@ -31,8 +31,11 @@ in description = "Extra appsettings.json configuration for the gateway offload daemon."; }; enableIdentify = lib.mkEnableOption "Enable offloading gateway opcode 2 (IDENTIFY)."; + enableGuildMembers = lib.mkEnableOption "Enable offloading gateway opcode 8 (REQUEST_GUILD_MEMBERS)."; enableGuildSync = lib.mkEnableOption "Enable offloading gateway opcode 12 (GUILD_SYNC)."; - enableLazyRequest = lib.mkEnableOption "Enable offloading gateway opcode 12 (LAZY_REQUEST)."; + enableLazyRequest = lib.mkEnableOption "Enable offloading gateway opcode 14 (LAZY_REQUEST)."; + enableChannelStatuses = lib.mkEnableOption "Enable offloading gateway opcode 36 (CHANNEL_STATUSES)."; + enableChannelInfo = lib.mkEnableOption "Enable offloading gateway opcode 43 (CHANNEL_INFO)."; }; }; }; @@ -48,9 +51,12 @@ in services.spacebarchat-server.settings.offload = { gateway = { - op2BaseUrl = lib.mkIf cfg.gatewayOffload.enableIdentify "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}"; - op12BaseUrl = lib.mkIf cfg.gatewayOffload.enableGuildSync "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}"; - op14BaseUrl = lib.mkIf cfg.gatewayOffload.enableLazyRequest "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}"; + identifyUrl = lib.mkIf cfg.gatewayOffload.enableIdentify "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}/_spacebar/offload/gateway/Identify"; + guildMembersUrl = lib.mkIf cfg.gatewayOffload.enableGuildMembers "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}/_spacebar/offload/gateway/GuildMembers"; + guildSyncUrlUrl = lib.mkIf cfg.gatewayOffload.enableGuildSync "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}/_spacebar/offload/gateway/GuildSync"; + lazyRequestUrl = lib.mkIf cfg.gatewayOffload.enableLazyRequest "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}/_spacebar/offload/gateway/LazyRequest"; + channelStatusesUrl = lib.mkIf cfg.gatewayOffload.enableChannelStatuses "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}/_spacebar/offload/gateway/ChannelStatuses"; + channelInfoUrl = lib.mkIf cfg.gatewayOffload.enableChannelInfo "http://127.0.0.1:${builtins.toString cfg.gatewayOffload.listenPort}/_spacebar/offload/gateway/ChannelInfo"; }; }; diff --git a/nix/testVm/configuration.nix b/nix/testVm/configuration.nix
index 5ba8caae..10bee8ec 100644 --- a/nix/testVm/configuration.nix +++ b/nix/testVm/configuration.nix
@@ -49,7 +49,12 @@ in gatewayOffload = { enable = true; + enableIdentify = true; + enableGuildMembers = true; enableGuildSync = true; + enableLazyRequest = true; + enableChannelStatuses = true; + enableChannelInfo = true; extraConfiguration.ConnectionStrings.Spacebar = csConnectionString; }; diff --git a/src/gateway/opcodes/GuildSync.ts b/src/gateway/opcodes/GuildSync.ts
index 34bfdb90..6a427ad7 100644 --- a/src/gateway/opcodes/GuildSync.ts +++ b/src/gateway/opcodes/GuildSync.ts
@@ -31,8 +31,9 @@ import { timePromise, Stopwatch, Guild, + Config, } from "@spacebar/util"; -import { WebSocket, Payload, handlePresenceUpdate, OPCODES, Send, getMostRelevantSession } from "@spacebar/gateway"; +import { WebSocket, Payload, handlePresenceUpdate, OPCODES, Send, getMostRelevantSession, handleOffloadedGatewayRequest } from "@spacebar/gateway"; import murmur from "murmurhash-js/murmurhash3_gc"; import { check } from "./instanceOf"; import { LazyRequestSchema, PublicMember } from "@spacebar/schemas"; @@ -45,6 +46,11 @@ import { In } from "typeorm"; export async function onGuildSync(this: WebSocket, { d }: Payload) { const sw = Stopwatch.startNew(); if (!Array.isArray(d)) throw new Error("Invalid payload for GUILD_SYNC"); + + if (Config.get().offload.gateway.guildSyncUrl !== null) { + return await handleOffloadedGatewayRequest(this, Config.get().offload.gateway.guildSyncUrl!, d); + } + const guild_ids = d as string[]; const joinedGuildIds = await Member.find({ where: { id: this.user_id, guild_id: In(guild_ids) }, select: { guild_id: true } }).then((members) => diff --git a/src/gateway/opcodes/RequestChannelInfo.ts b/src/gateway/opcodes/RequestChannelInfo.ts
index f0c7e9ce..efa3e728 100644 --- a/src/gateway/opcodes/RequestChannelInfo.ts +++ b/src/gateway/opcodes/RequestChannelInfo.ts
@@ -16,15 +16,19 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { WebSocket, Payload, OPCODES, Send } from "@spacebar/gateway"; +import { WebSocket, Payload, OPCODES, Send, handleOffloadedGatewayRequest } from "@spacebar/gateway"; import { ChannelType } from "@spacebar/schemas"; -import { Channel } from "@spacebar/util"; +import { Channel, Config } from "@spacebar/util"; export async function onRequestChannelInfo(this: WebSocket, { d }: Payload) { // Schema validation can only accept either string or array, so transforming it here to support both if (!d.guild_id) throw new Error('"guild_id" is required'); if (!d.fields) throw new Error('"fields" is required'); + if (Config.get().offload.gateway.channelInfoUrl !== null) { + return await handleOffloadedGatewayRequest(this, Config.get().offload.gateway.channelInfoUrl!, d); + } + const channels = ( await Channel.find({ where: { guild_id: d.guild_id, type: ChannelType.GUILD_VOICE }, diff --git a/src/gateway/opcodes/RequestChannelStatuses.ts b/src/gateway/opcodes/RequestChannelStatuses.ts
index 533ece22..1747faae 100644 --- a/src/gateway/opcodes/RequestChannelStatuses.ts +++ b/src/gateway/opcodes/RequestChannelStatuses.ts
@@ -16,12 +16,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { WebSocket, Payload, OPCODES, Send } from "@spacebar/gateway"; +import { WebSocket, Payload, OPCODES, Send, handleOffloadedGatewayRequest } from "@spacebar/gateway"; +import { Config } from "@spacebar/util"; export async function onRequestChannelStatuses(this: WebSocket, { d }: Payload) { // Schema validation can only accept either string or array, so transforming it here to support both if (!d.guild_id) throw new Error('"guild_id" is required'); + if (Config.get().offload.gateway.channelStatusesUrl !== null) { + return await handleOffloadedGatewayRequest(this, Config.get().offload.gateway.channelStatusesUrl!, d); + } + // TODO: implement await Send(this, { op: OPCODES.Dispatch, diff --git a/src/gateway/opcodes/RequestGuildMembers.ts b/src/gateway/opcodes/RequestGuildMembers.ts
index 0e65b6cc..cba2c89c 100644 --- a/src/gateway/opcodes/RequestGuildMembers.ts +++ b/src/gateway/opcodes/RequestGuildMembers.ts
@@ -16,8 +16,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { DateBuilder, getDatabase, getPermission, GuildMembersChunkEvent, Member, Presence, Session } from "@spacebar/util"; -import { WebSocket, Payload, OPCODES, Send } from "@spacebar/gateway"; +import { Config, DateBuilder, getDatabase, getPermission, GuildMembersChunkEvent, Member, Presence, Session } from "@spacebar/util"; +import { WebSocket, Payload, OPCODES, Send, handleOffloadedGatewayRequest } from "@spacebar/gateway"; import { check } from "./instanceOf"; import { FindManyOptions, ILike, In, MoreThan } from "typeorm"; import { RequestGuildMembersSchema } from "@spacebar/schemas"; @@ -30,6 +30,10 @@ export async function onRequestGuildMembers(this: WebSocket, { d }: Payload) { if (d.user_ids && !Array.isArray(d.user_ids)) d.user_ids = [d.user_ids]; + if (Config.get().offload.gateway.guildMembersUrl !== null) { + return await handleOffloadedGatewayRequest(this, Config.get().offload.gateway.guildMembersUrl!, d); + } + check.call(this, RequestGuildMembersSchema, d); const { presences, nonce, query: requestQuery } = d as RequestGuildMembersSchema; diff --git a/src/gateway/util/Utils.ts b/src/gateway/util/Utils.ts
index 74ec33cf..ec0f411c 100644 --- a/src/gateway/util/Utils.ts +++ b/src/gateway/util/Utils.ts
@@ -77,6 +77,7 @@ export async function handleOffloadedGatewayRequest(socket: WebSocket, url: stri if (!resp.ok) { const text = await resp.text(); console.error(`[Gateway] Offloaded request to ${url} failed with status ${resp.status}: ${text}`); + if (resp.status === 415) console.log(typeof body, body); throw new Error(`Offloaded request failed with status ${resp.status}: ${text}`); } diff --git a/src/util/config/types/OffloadConfiguration.ts b/src/util/config/types/OffloadConfiguration.ts
index b52919fb..fd15df6d 100644 --- a/src/util/config/types/OffloadConfiguration.ts +++ b/src/util/config/types/OffloadConfiguration.ts
@@ -21,6 +21,9 @@ export class OffloadConfiguration { } export class GatewayOffloadConfiguration { - op12BaseUrl: string | null = null; - op14BaseUrl: string | null = null; + guildMembersUrl: string | null = null; // op8 + guildSyncUrl: string | null = null; // op12 + lazyRequestUrl: string | null = null; // op14 + channelStatusesUrl: string | null = null; //op36 + channelInfoUrl: string | null = null; //op43 } diff --git a/src/util/util/Decorators.ts b/src/util/util/Decorators.ts
index dd2ec1b2..18910b9d 100644 --- a/src/util/util/Decorators.ts +++ b/src/util/util/Decorators.ts
@@ -1,4 +1,4 @@ -import { BaseClassWithoutId } from "@spacebar/util*"; +import { BaseClassWithoutId } from "@spacebar/util"; export const annotationsKey = Symbol("Annotations");