mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
fix(message): bound batched message response requests by size (#2252)
This commit is contained in:
@@ -15,6 +15,7 @@ import {isJsonRecord, parseJsonRecord, parseJsonWithGuard} from '../../../utils/
|
||||
|
||||
const MESSAGE_RESPONSE_SERVICE_SUBJECT = 'svc.messages';
|
||||
const MESSAGE_RESPONSE_SERVICE_TIMEOUT_MS = 6000;
|
||||
export const MESSAGE_BUILD_BATCH_MAX_BYTES = 262_144;
|
||||
let messageResponseDataService: MessageResponseDataService | undefined;
|
||||
let injectedMessageResponseDataService: MessageResponseDataService | undefined;
|
||||
|
||||
@@ -230,23 +231,27 @@ export class MessageResponseDataService {
|
||||
includeReactions?: boolean;
|
||||
}): Promise<Array<MessageResponse>> {
|
||||
if (params.messages.length === 0) return [];
|
||||
const response = await this.request({
|
||||
op: 'BuildResponses',
|
||||
messages: params.messages.map(serializeMessageForService),
|
||||
viewer_user_id: params.userId.toString(),
|
||||
source_guild_id: params.access.sourceGuildId?.toString(),
|
||||
message_history_cutoff_ms: params.access.messageHistoryCutoff
|
||||
? new Date(params.access.messageHistoryCutoff).getTime()
|
||||
: null,
|
||||
can_read_message_history: params.access.canReadMessageHistory,
|
||||
media_endpoint: Config.endpoints.media,
|
||||
media_proxy_secret_key: Config.mediaProxy.secretKey,
|
||||
include_reactions: params.includeReactions ?? true,
|
||||
});
|
||||
if (typeof response === 'object' && 'FoundApiMany' in response) {
|
||||
return response.FoundApiMany;
|
||||
const responses: Array<MessageResponse> = [];
|
||||
for (const batch of chunkMessagesForService(params.messages)) {
|
||||
const response = await this.request({
|
||||
op: 'BuildResponses',
|
||||
messages: batch,
|
||||
viewer_user_id: params.userId.toString(),
|
||||
source_guild_id: params.access.sourceGuildId?.toString(),
|
||||
message_history_cutoff_ms: params.access.messageHistoryCutoff
|
||||
? new Date(params.access.messageHistoryCutoff).getTime()
|
||||
: null,
|
||||
can_read_message_history: params.access.canReadMessageHistory,
|
||||
media_endpoint: Config.endpoints.media,
|
||||
media_proxy_secret_key: Config.mediaProxy.secretKey,
|
||||
include_reactions: params.includeReactions ?? true,
|
||||
});
|
||||
if (typeof response !== 'object' || !('FoundApiMany' in response)) {
|
||||
throw new Error(`[message-response-service] unexpected BuildResponses response: ${JSON.stringify(response)}`);
|
||||
}
|
||||
responses.push(...response.FoundApiMany);
|
||||
}
|
||||
throw new Error(`[message-response-service] unexpected BuildResponses response: ${JSON.stringify(response)}`);
|
||||
return responses;
|
||||
}
|
||||
|
||||
async buildMessagesForChannels(params: {
|
||||
@@ -340,6 +345,27 @@ function serializeMessageForService(message: Message): Record<string, unknown> {
|
||||
return row;
|
||||
}
|
||||
|
||||
function chunkMessagesForService(messages: Array<Message>): Array<Array<Record<string, unknown>>> {
|
||||
const batches: Array<Array<Record<string, unknown>>> = [];
|
||||
let batch: Array<Record<string, unknown>> = [];
|
||||
let batchBytes = 0;
|
||||
for (const message of messages) {
|
||||
const serialized = serializeMessageForService(message);
|
||||
const bytes = Buffer.byteLength(JSON.stringify(serialized));
|
||||
if (batch.length > 0 && batchBytes + bytes > MESSAGE_BUILD_BATCH_MAX_BYTES) {
|
||||
batches.push(batch);
|
||||
batch = [];
|
||||
batchBytes = 0;
|
||||
}
|
||||
batch.push(serialized);
|
||||
batchBytes += bytes;
|
||||
}
|
||||
if (batch.length > 0) {
|
||||
batches.push(batch);
|
||||
}
|
||||
return batches;
|
||||
}
|
||||
|
||||
function serializeValue(value: unknown): unknown {
|
||||
if (value == null) return value;
|
||||
if (typeof value === 'bigint') return value.toString();
|
||||
|
||||
Reference in New Issue
Block a user