mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
perf(gateway): speed up presence and harden guild queries (#3072)
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
export const GatewayRpcMethodErrorCodes = {
|
||||
OVERLOADED: 'overloaded',
|
||||
GUILD_OVERLOADED: 'guild_overloaded',
|
||||
INTERNAL_ERROR: 'internal_error',
|
||||
TIMEOUT: 'timeout',
|
||||
NO_RESPONDERS: 'no_responders',
|
||||
|
||||
@@ -296,6 +296,9 @@ export class GatewayService {
|
||||
if (error.code === GatewayRpcMethodErrorCodes.TIMEOUT) {
|
||||
return new GatewayTimeoutError();
|
||||
}
|
||||
if (error.code === GatewayRpcMethodErrorCodes.GUILD_OVERLOADED) {
|
||||
return new ServiceUnavailableError({headers: {'Retry-After': '1'}});
|
||||
}
|
||||
if (error.code === GatewayRpcMethodErrorCodes.OVERLOADED) {
|
||||
return new ServiceUnavailableError();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {IGatewayRpcTransport} from '@app/api/infrastructure/IGatewayRpcTran
|
||||
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
|
||||
import {BadGatewayError} from '@fluxer/errors/src/domains/core/BadGatewayError';
|
||||
import {BadRequestError} from '@fluxer/errors/src/domains/core/BadRequestError';
|
||||
import {ServiceUnavailableError} from '@fluxer/errors/src/domains/core/ServiceUnavailableError';
|
||||
import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildError';
|
||||
import {afterEach, describe, expect, it} from 'vitest';
|
||||
|
||||
@@ -70,4 +71,30 @@ describe('GatewayService gateway error mapping', () => {
|
||||
expect((error as BadRequestError).status).toBe(400);
|
||||
expect((error as BadRequestError).code).toBe(APIErrorCodes.INVALID_FORM_BODY);
|
||||
});
|
||||
|
||||
it('returns 503 with Retry-After for an overloaded guild', async () => {
|
||||
const service = serviceRaising(GatewayRpcMethodErrorCodes.GUILD_OVERLOADED);
|
||||
const error = await service
|
||||
.getUserPermissions({guildId: createGuildID(1n), userId: createUserID(2n)})
|
||||
.catch((raised: unknown) => raised);
|
||||
expect(error).toBeInstanceOf(ServiceUnavailableError);
|
||||
const response = (error as ServiceUnavailableError).getResponse();
|
||||
expect(response.status).toBe(503);
|
||||
expect(response.headers.get('Retry-After')).toBe('1');
|
||||
});
|
||||
|
||||
it('does not retry a guild overload response', async () => {
|
||||
let calls = 0;
|
||||
const client = GatewayRpcClient.createForTests({
|
||||
async call(): Promise<unknown> {
|
||||
calls += 1;
|
||||
throw new GatewayRpcMethodError(GatewayRpcMethodErrorCodes.GUILD_OVERLOADED);
|
||||
},
|
||||
async destroy(): Promise<void> {},
|
||||
});
|
||||
await expect(client.call('guild.dispatch', {guild_id: '1'})).rejects.toMatchObject({
|
||||
code: GatewayRpcMethodErrorCodes.GUILD_OVERLOADED,
|
||||
});
|
||||
expect(calls).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user