fix(api): batch member user lookups on guild load (#2783)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-14 23:06:36 +02:00
1 parent c212d315f4
commit 50cec92738
4 files changed
+26 -4

No files matched your search

+4
View File
@@ -795,6 +795,10 @@ export class RpcService {
requestCache: RequestCache;
}): Promise<Array<GuildMemberResponse>> {
const {guildId, members, requestCache} = params;
await this.userCacheService.getUserPartialResponses(
members.map((member) => member.userId),
requestCache,
);
const mappedMembers = await allSettledWithConcurrency(members, RPC_RESPONSE_MAP_CONCURRENCY, (member) =>
mapGuildMemberToResponse(member, this.userCacheService, requestCache),
);
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {setupTestGuildWithMembers} from '@app/api/guild/tests/GuildTestUtils';
import {createUsersServiceClient} from '@app/api/infrastructure/UsersServiceClient';
import {type ApiTestHarness, createApiTestHarness} from '@app/api/test/ApiTestHarness';
import {HTTP_STATUS, TEST_IDS} from '@app/api/test/TestConstants';
import {createBuilder} from '@app/api/test/TestRequestBuilder';
import {RpcRequest} from '@fluxer/schema/src/domains/rpc/RpcSchemas';
import {afterEach, beforeEach, describe, expect, test} from 'vitest';
import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest';
interface RpcGuildCollectionMembersResponse {
type: 'guild_collection';
@@ -69,6 +70,22 @@ describe('RpcService guild member collection pagination', () => {
expect(seenIds.slice().sort()).toStrictEqual(expectedIds.slice().sort());
});
test('looks up every member user on a page in one users service request', async () => {
const {owner, members, guild} = await setupTestGuildWithMembers(harness, 3);
const memberIds = [owner.userId, ...members.map((member) => member.userId)].sort();
const lookups = vi.spyOn(createUsersServiceClient(), 'getUserPartialResponses');
try {
const data = await fetchMemberPage(harness, guild.id, 1000);
expect(data.members.map((member) => member.user.id).sort()).toStrictEqual(memberIds);
const memberLookups = lookups.mock.calls
.map(([userIds]) => userIds.map(String).sort())
.filter((userIds) => userIds.some((userId) => memberIds.includes(userId)));
expect(memberLookups).toStrictEqual([memberIds]);
} finally {
lookups.mockRestore();
}
});
test('rejects an unknown guild on the first member page', async () => {
await createBuilder(harness, '')
.post('/test/rpc-session-init')