mirror of
https://github.com/spacebarchat/server.git
synced 2026-05-14 20:35:17 +00:00
gateway offload work
This commit is contained in:
@@ -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 = [
|
||||
|
||||
@@ -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("")]
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,12 @@ in
|
||||
|
||||
gatewayOffload = {
|
||||
enable = true;
|
||||
enableIdentify = true;
|
||||
enableGuildMembers = true;
|
||||
enableGuildSync = true;
|
||||
enableLazyRequest = true;
|
||||
enableChannelStatuses = true;
|
||||
enableChannelInfo = true;
|
||||
extraConfiguration.ConnectionStrings.Spacebar = csConnectionString;
|
||||
};
|
||||
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BaseClassWithoutId } from "@spacebar/util*";
|
||||
import { BaseClassWithoutId } from "@spacebar/util";
|
||||
|
||||
export const annotationsKey = Symbol("Annotations");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user