mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
feat(api): add managed guild invite pauses (#3419)
This commit is contained in:
1 parent
c890956e4f
commit
17746fcdc4
28 files changed
+1203
-60
No files matched your search
@@ -25,6 +25,7 @@ import {
|
||||
THREAD_AUDIT_LOG_ACTION_TYPES,
|
||||
} from '@app/api/guild/GuildAuditLogEntryMapper';
|
||||
import type {GuildAuditLogService} from '@app/api/guild/GuildAuditLogService';
|
||||
import {withGuildUpdateLock} from '@app/api/guild/GuildUpdateLock';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import {GuildChannelService} from '@app/api/guild/services/GuildChannelService';
|
||||
import {GuildContentService} from '@app/api/guild/services/GuildContentService';
|
||||
@@ -53,7 +54,6 @@ import {THREAD_FEATURE_CHANNEL_TYPES} from '@fluxer/constants/src/ThreadConstant
|
||||
import {ValidationErrorCodes} from '@fluxer/constants/src/ValidationErrorCodes';
|
||||
import {InputValidationError} from '@fluxer/errors/src/domains/core/InputValidationError';
|
||||
import {MissingPermissionsError} from '@fluxer/errors/src/domains/core/MissingPermissionsError';
|
||||
import {ResourceLockedError} from '@fluxer/errors/src/domains/core/ResourceLockedError';
|
||||
import {UnknownGuildEmojiError} from '@fluxer/errors/src/domains/guild/UnknownGuildEmojiError';
|
||||
import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildError';
|
||||
import {UnknownGuildStickerError} from '@fluxer/errors/src/domains/guild/UnknownGuildStickerError';
|
||||
@@ -80,10 +80,6 @@ interface StoredGuildAuditLogListResponse extends Omit<GuildAuditLogListResponse
|
||||
webhooks: Array<StoredAuditLogWebhookResponse>;
|
||||
}
|
||||
|
||||
const GUILD_UPDATE_LOCK_TTL_SECONDS = 10;
|
||||
const GUILD_UPDATE_LOCK_RETRY_DELAY_MS = 50;
|
||||
const GUILD_UPDATE_LOCK_MAX_WAIT_MS = 5000;
|
||||
|
||||
export class GuildService {
|
||||
public readonly data: GuildDataService;
|
||||
public readonly members: GuildMemberService;
|
||||
@@ -211,9 +207,10 @@ export class GuildService {
|
||||
auditLogReason?: string | null,
|
||||
): Promise<GuildResponse> {
|
||||
const {guildId, requestCache} = params;
|
||||
const {guild, previousFeatures, updatedFeatures} = await this.withGuildUpdateLock(guildId, requestCache, () =>
|
||||
this.data.operations.updateGuild(params, auditLogReason),
|
||||
);
|
||||
const {guild, previousFeatures, updatedFeatures} = await this.withUpdateLock(guildId, () => {
|
||||
requestCache.guilds.delete(guildId);
|
||||
return this.data.operations.updateGuild(params, auditLogReason);
|
||||
});
|
||||
if (
|
||||
previousFeatures.has(GuildFeatures.TEXT_CHANNEL_FLEXIBLE_NAMES) &&
|
||||
!updatedFeatures.has(GuildFeatures.TEXT_CHANNEL_FLEXIBLE_NAMES)
|
||||
@@ -223,30 +220,8 @@ export class GuildService {
|
||||
return guild;
|
||||
}
|
||||
|
||||
private async withGuildUpdateLock<T>(guildId: GuildID, requestCache: RequestCache, fn: () => Promise<T>): Promise<T> {
|
||||
const lockKey = `guild:${guildId}:update`;
|
||||
const lockToken = await this.acquireGuildUpdateLock(lockKey);
|
||||
if (!lockToken) {
|
||||
throw new ResourceLockedError();
|
||||
}
|
||||
try {
|
||||
requestCache.guilds.delete(guildId);
|
||||
return await fn();
|
||||
} finally {
|
||||
await this.cacheService.releaseLock(lockKey, lockToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async acquireGuildUpdateLock(lockKey: string): Promise<string | null> {
|
||||
const startTime = Date.now();
|
||||
while (Date.now() - startTime < GUILD_UPDATE_LOCK_MAX_WAIT_MS) {
|
||||
const token = await this.cacheService.acquireLock(lockKey, GUILD_UPDATE_LOCK_TTL_SECONDS);
|
||||
if (token) {
|
||||
return token;
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, GUILD_UPDATE_LOCK_RETRY_DELAY_MS));
|
||||
}
|
||||
return null;
|
||||
withUpdateLock<T>(guildId: GuildID, fn: () => Promise<T>): Promise<T> {
|
||||
return withGuildUpdateLock(this.cacheService, guildId, fn);
|
||||
}
|
||||
|
||||
async getEmojiMetadata(emojiId: EmojiID): Promise<GuildEmojiMetadataResponse> {
|
||||
|
||||
Reference in new issue
Block a user