refactor progress
This commit is contained in:
406
packages/api/src/worker/WorkerDependencies.tsx
Normal file
406
packages/api/src/worker/WorkerDependencies.tsx
Normal file
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {AdminRepository} from '@fluxer/api/src/admin/AdminRepository';
|
||||
import {AdminArchiveRepository} from '@fluxer/api/src/admin/repositories/AdminArchiveRepository';
|
||||
import {SystemDmJobRepository} from '@fluxer/api/src/admin/repositories/SystemDmJobRepository';
|
||||
import {Config} from '@fluxer/api/src/Config';
|
||||
import {ChannelRepository} from '@fluxer/api/src/channel/ChannelRepository';
|
||||
import {ChannelService} from '@fluxer/api/src/channel/services/ChannelService';
|
||||
import {ConnectionRepository} from '@fluxer/api/src/connection/ConnectionRepository';
|
||||
import {ConnectionService} from '@fluxer/api/src/connection/ConnectionService';
|
||||
import {CsamEvidenceRetentionService} from '@fluxer/api/src/csam/CsamEvidenceRetentionService';
|
||||
import {CsamScanJobService} from '@fluxer/api/src/csam/CsamScanJobService';
|
||||
import {createEmailProvider} from '@fluxer/api/src/email/EmailProviderFactory';
|
||||
import {FavoriteMemeRepository} from '@fluxer/api/src/favorite_meme/FavoriteMemeRepository';
|
||||
import {GuildAuditLogService} from '@fluxer/api/src/guild/GuildAuditLogService';
|
||||
import {GuildRepository} from '@fluxer/api/src/guild/repositories/GuildRepository';
|
||||
import {ExpressionAssetPurger} from '@fluxer/api/src/guild/services/content/ExpressionAssetPurger';
|
||||
import {GuildService} from '@fluxer/api/src/guild/services/GuildService';
|
||||
import {AssetDeletionQueue} from '@fluxer/api/src/infrastructure/AssetDeletionQueue';
|
||||
import {AvatarService} from '@fluxer/api/src/infrastructure/AvatarService';
|
||||
import {CloudflarePurgeQueue, NoopPurgeQueue} from '@fluxer/api/src/infrastructure/CloudflarePurgeQueue';
|
||||
import {DisabledLiveKitService} from '@fluxer/api/src/infrastructure/DisabledLiveKitService';
|
||||
import {DiscriminatorService} from '@fluxer/api/src/infrastructure/DiscriminatorService';
|
||||
import {EmbedService} from '@fluxer/api/src/infrastructure/EmbedService';
|
||||
import {EntityAssetService} from '@fluxer/api/src/infrastructure/EntityAssetService';
|
||||
import type {IGatewayService} from '@fluxer/api/src/infrastructure/IGatewayService';
|
||||
import type {ILiveKitService} from '@fluxer/api/src/infrastructure/ILiveKitService';
|
||||
import type {IMediaService} from '@fluxer/api/src/infrastructure/IMediaService';
|
||||
import {InMemoryVoiceRoomStore} from '@fluxer/api/src/infrastructure/InMemoryVoiceRoomStore';
|
||||
import type {IStorageService} from '@fluxer/api/src/infrastructure/IStorageService';
|
||||
import type {IVoiceRoomStore} from '@fluxer/api/src/infrastructure/IVoiceRoomStore';
|
||||
import {KVAccountDeletionQueueService} from '@fluxer/api/src/infrastructure/KVAccountDeletionQueueService';
|
||||
import {KVActivityTracker} from '@fluxer/api/src/infrastructure/KVActivityTracker';
|
||||
import {KVBulkMessageDeletionQueueService} from '@fluxer/api/src/infrastructure/KVBulkMessageDeletionQueueService';
|
||||
import {LiveKitService} from '@fluxer/api/src/infrastructure/LiveKitService';
|
||||
import type {SnowflakeService} from '@fluxer/api/src/infrastructure/SnowflakeService';
|
||||
import {createStorageService} from '@fluxer/api/src/infrastructure/StorageServiceFactory';
|
||||
import {UnfurlerService} from '@fluxer/api/src/infrastructure/UnfurlerService';
|
||||
import {UserCacheService} from '@fluxer/api/src/infrastructure/UserCacheService';
|
||||
import {VirusScanService} from '@fluxer/api/src/infrastructure/VirusScanService';
|
||||
import {VoiceRoomStore} from '@fluxer/api/src/infrastructure/VoiceRoomStore';
|
||||
import {InstanceConfigRepository} from '@fluxer/api/src/instance/InstanceConfigRepository';
|
||||
import {InviteRepository} from '@fluxer/api/src/invite/InviteRepository';
|
||||
import {InviteService} from '@fluxer/api/src/invite/InviteService';
|
||||
import {Logger} from '@fluxer/api/src/Logger';
|
||||
import {LimitConfigService} from '@fluxer/api/src/limits/LimitConfigService';
|
||||
import {
|
||||
getGatewayService,
|
||||
getInjectedS3Service,
|
||||
getKVClient,
|
||||
getMediaService,
|
||||
getWorkerService,
|
||||
} from '@fluxer/api/src/middleware/ServiceRegistry';
|
||||
import {ApplicationRepository} from '@fluxer/api/src/oauth/repositories/ApplicationRepository';
|
||||
import {OAuth2TokenRepository} from '@fluxer/api/src/oauth/repositories/OAuth2TokenRepository';
|
||||
import {PackRepository} from '@fluxer/api/src/pack/PackRepository';
|
||||
import {PackService} from '@fluxer/api/src/pack/PackService';
|
||||
import {ReadStateRepository} from '@fluxer/api/src/read_state/ReadStateRepository';
|
||||
import {ReadStateService} from '@fluxer/api/src/read_state/ReadStateService';
|
||||
import {ReportRepository} from '@fluxer/api/src/report/ReportRepository';
|
||||
import {PaymentRepository} from '@fluxer/api/src/user/repositories/PaymentRepository';
|
||||
import {UserContactChangeLogRepository} from '@fluxer/api/src/user/repositories/UserContactChangeLogRepository';
|
||||
import {UserRepository} from '@fluxer/api/src/user/repositories/UserRepository';
|
||||
import {UserContactChangeLogService} from '@fluxer/api/src/user/services/UserContactChangeLogService';
|
||||
import {UserDeletionEligibilityService} from '@fluxer/api/src/user/services/UserDeletionEligibilityService';
|
||||
import {UserHarvestRepository} from '@fluxer/api/src/user/UserHarvestRepository';
|
||||
import {UserPermissionUtils} from '@fluxer/api/src/utils/UserPermissionUtils';
|
||||
import {VoiceRepository} from '@fluxer/api/src/voice/VoiceRepository';
|
||||
import {VoiceTopology} from '@fluxer/api/src/voice/VoiceTopology';
|
||||
import {WebhookRepository} from '@fluxer/api/src/webhook/WebhookRepository';
|
||||
import {KVCacheProvider} from '@fluxer/cache/src/providers/KVCacheProvider';
|
||||
import {EmailI18nService} from '@fluxer/email/src/EmailI18nService';
|
||||
import type {EmailConfig, UserBouncedEmailChecker} from '@fluxer/email/src/EmailProviderTypes';
|
||||
import {EmailService} from '@fluxer/email/src/EmailService';
|
||||
import type {IEmailService} from '@fluxer/email/src/IEmailService';
|
||||
import {TestEmailService} from '@fluxer/email/src/TestEmailService';
|
||||
import type {IKVProvider} from '@fluxer/kv_client/src/IKVProvider';
|
||||
import {RateLimitService} from '@fluxer/rate_limit/src/RateLimitService';
|
||||
import type {IWorkerService} from '@fluxer/worker/src/contracts/IWorkerService';
|
||||
import Stripe from 'stripe';
|
||||
|
||||
let _workerTestEmailService: TestEmailService | null = null;
|
||||
function getWorkerTestEmailService(): TestEmailService {
|
||||
if (!_workerTestEmailService) {
|
||||
_workerTestEmailService = new TestEmailService();
|
||||
}
|
||||
return _workerTestEmailService;
|
||||
}
|
||||
|
||||
export interface WorkerDependencies {
|
||||
kvClient: IKVProvider;
|
||||
snowflakeService: SnowflakeService;
|
||||
limitConfigService: LimitConfigService;
|
||||
|
||||
userRepository: UserRepository;
|
||||
channelRepository: ChannelRepository;
|
||||
guildRepository: GuildRepository;
|
||||
favoriteMemeRepository: FavoriteMemeRepository;
|
||||
applicationRepository: ApplicationRepository;
|
||||
oauth2TokenRepository: OAuth2TokenRepository;
|
||||
readStateRepository: ReadStateRepository;
|
||||
adminRepository: AdminRepository;
|
||||
reportRepository: ReportRepository;
|
||||
paymentRepository: PaymentRepository;
|
||||
userHarvestRepository: UserHarvestRepository;
|
||||
adminArchiveRepository: AdminArchiveRepository;
|
||||
systemDmJobRepository: SystemDmJobRepository;
|
||||
voiceRepository: VoiceRepository | null;
|
||||
connectionRepository: ConnectionRepository;
|
||||
connectionService: ConnectionService;
|
||||
|
||||
cacheService: KVCacheProvider;
|
||||
userCacheService: UserCacheService;
|
||||
storageService: IStorageService;
|
||||
assetDeletionQueue: AssetDeletionQueue;
|
||||
purgeQueue: CloudflarePurgeQueue | NoopPurgeQueue;
|
||||
|
||||
gatewayService: IGatewayService;
|
||||
mediaService: IMediaService;
|
||||
discriminatorService: DiscriminatorService;
|
||||
avatarService: AvatarService;
|
||||
virusScanService: VirusScanService;
|
||||
rateLimitService: RateLimitService;
|
||||
emailService: IEmailService;
|
||||
inviteService: InviteService;
|
||||
|
||||
workerService: IWorkerService;
|
||||
unfurlerService: UnfurlerService;
|
||||
embedService: EmbedService;
|
||||
readStateService: ReadStateService;
|
||||
userPermissionUtils: UserPermissionUtils;
|
||||
activityTracker: KVActivityTracker;
|
||||
deletionQueueService: KVAccountDeletionQueueService;
|
||||
bulkMessageDeletionQueueService: KVBulkMessageDeletionQueueService;
|
||||
deletionEligibilityService: UserDeletionEligibilityService;
|
||||
|
||||
voiceRoomStore: IVoiceRoomStore;
|
||||
liveKitService: ILiveKitService;
|
||||
voiceTopology: VoiceTopology | null;
|
||||
|
||||
channelService: ChannelService;
|
||||
guildAuditLogService: GuildAuditLogService;
|
||||
contactChangeLogService: UserContactChangeLogService;
|
||||
csamEvidenceRetentionService: CsamEvidenceRetentionService;
|
||||
|
||||
stripe: Stripe | null;
|
||||
csamScanJobService: CsamScanJobService;
|
||||
}
|
||||
|
||||
export async function initializeWorkerDependencies(snowflakeService: SnowflakeService): Promise<WorkerDependencies> {
|
||||
Logger.info('Initializing worker dependencies...');
|
||||
|
||||
const kvClient = getKVClient();
|
||||
|
||||
const userRepository = new UserRepository();
|
||||
const channelRepository = new ChannelRepository();
|
||||
const guildRepository = new GuildRepository();
|
||||
const favoriteMemeRepository = new FavoriteMemeRepository();
|
||||
const applicationRepository = new ApplicationRepository();
|
||||
const oauth2TokenRepository = new OAuth2TokenRepository();
|
||||
const readStateRepository = new ReadStateRepository();
|
||||
const adminRepository = new AdminRepository();
|
||||
const adminArchiveRepository = new AdminArchiveRepository();
|
||||
const systemDmJobRepository = new SystemDmJobRepository();
|
||||
const reportRepository = new ReportRepository();
|
||||
const paymentRepository = new PaymentRepository();
|
||||
const userHarvestRepository = new UserHarvestRepository();
|
||||
const contactChangeLogRepository = new UserContactChangeLogRepository();
|
||||
const contactChangeLogService = new UserContactChangeLogService(contactChangeLogRepository);
|
||||
const connectionRepository = new ConnectionRepository();
|
||||
|
||||
const cacheService = new KVCacheProvider({client: kvClient});
|
||||
const instanceConfigRepository = new InstanceConfigRepository();
|
||||
const limitConfigSubscriber = getKVClient();
|
||||
const limitConfigService = new LimitConfigService(instanceConfigRepository, cacheService, limitConfigSubscriber);
|
||||
await limitConfigService.initialize();
|
||||
const userCacheService = new UserCacheService(cacheService, userRepository);
|
||||
const storageService = createStorageService({s3Service: getInjectedS3Service()});
|
||||
const csamEvidenceRetentionService = new CsamEvidenceRetentionService(storageService);
|
||||
const assetDeletionQueue = new AssetDeletionQueue(kvClient);
|
||||
const purgeQueue = Config.cloudflare.purgeEnabled ? new CloudflarePurgeQueue(kvClient) : new NoopPurgeQueue();
|
||||
|
||||
const gatewayService = getGatewayService();
|
||||
const connectionService = new ConnectionService(connectionRepository, gatewayService, null);
|
||||
const mediaService = getMediaService();
|
||||
const discriminatorService = new DiscriminatorService(userRepository, cacheService, limitConfigService);
|
||||
const avatarService = new AvatarService(storageService, mediaService, limitConfigService);
|
||||
const entityAssetService = new EntityAssetService(
|
||||
storageService,
|
||||
mediaService,
|
||||
assetDeletionQueue,
|
||||
limitConfigService,
|
||||
);
|
||||
const virusScanService = new VirusScanService(cacheService);
|
||||
const rateLimitService = new RateLimitService(cacheService);
|
||||
const packRepository = new PackRepository();
|
||||
const packAssetPurger = new ExpressionAssetPurger(assetDeletionQueue);
|
||||
const packService = new PackService(
|
||||
packRepository,
|
||||
guildRepository,
|
||||
avatarService,
|
||||
snowflakeService,
|
||||
packAssetPurger,
|
||||
userRepository,
|
||||
userCacheService,
|
||||
limitConfigService,
|
||||
);
|
||||
const emailConfig: EmailConfig = {
|
||||
enabled: Config.email.enabled,
|
||||
fromEmail: Config.email.fromEmail,
|
||||
fromName: Config.email.fromName,
|
||||
appBaseUrl: Config.endpoints.webApp,
|
||||
marketingBaseUrl: Config.endpoints.marketing,
|
||||
};
|
||||
|
||||
const bouncedEmailChecker: UserBouncedEmailChecker = {
|
||||
isEmailBounced: async (email: string) => {
|
||||
const user = await userRepository.findByEmail(email);
|
||||
return user?.emailBounced ?? false;
|
||||
},
|
||||
};
|
||||
|
||||
const emailI18n = new EmailI18nService();
|
||||
const emailProvider = createEmailProvider(Config.email);
|
||||
const emailService: IEmailService = Config.dev.testModeEnabled
|
||||
? getWorkerTestEmailService()
|
||||
: new EmailService(emailConfig, emailI18n, emailProvider, bouncedEmailChecker);
|
||||
|
||||
const workerService = getWorkerService();
|
||||
const guildAuditLogService = new GuildAuditLogService(guildRepository, snowflakeService, workerService);
|
||||
const unfurlerService = new UnfurlerService(cacheService, mediaService);
|
||||
const embedService = new EmbedService(channelRepository, cacheService, unfurlerService, mediaService, workerService);
|
||||
const readStateService = new ReadStateService(readStateRepository, gatewayService);
|
||||
const userPermissionUtils = new UserPermissionUtils(userRepository, guildRepository);
|
||||
const activityTracker = new KVActivityTracker(kvClient);
|
||||
const deletionQueueService = new KVAccountDeletionQueueService(kvClient, userRepository);
|
||||
const bulkMessageDeletionQueueService = new KVBulkMessageDeletionQueueService(kvClient);
|
||||
const deletionEligibilityService = new UserDeletionEligibilityService(kvClient);
|
||||
const csamScanJobService = new CsamScanJobService();
|
||||
|
||||
let voiceRepository: VoiceRepository | null = null;
|
||||
let voiceTopology: VoiceTopology | null = null;
|
||||
let voiceRoomStore: IVoiceRoomStore;
|
||||
let liveKitService: ILiveKitService;
|
||||
|
||||
if (Config.voice.enabled) {
|
||||
voiceRepository = new VoiceRepository();
|
||||
voiceTopology = new VoiceTopology(voiceRepository, null);
|
||||
await voiceTopology.initialize();
|
||||
voiceRoomStore = new VoiceRoomStore(kvClient);
|
||||
liveKitService = new LiveKitService(voiceTopology);
|
||||
Logger.info('Voice services initialized');
|
||||
} else {
|
||||
voiceRoomStore = new InMemoryVoiceRoomStore();
|
||||
liveKitService = new DisabledLiveKitService();
|
||||
}
|
||||
|
||||
const inviteRepository = new InviteRepository();
|
||||
const webhookRepository = new WebhookRepository();
|
||||
|
||||
const channelService = new ChannelService(
|
||||
channelRepository,
|
||||
userRepository,
|
||||
guildRepository,
|
||||
packService,
|
||||
userCacheService,
|
||||
embedService,
|
||||
readStateService,
|
||||
cacheService,
|
||||
storageService,
|
||||
gatewayService,
|
||||
mediaService,
|
||||
avatarService,
|
||||
workerService,
|
||||
virusScanService,
|
||||
snowflakeService,
|
||||
rateLimitService,
|
||||
purgeQueue,
|
||||
favoriteMemeRepository,
|
||||
guildAuditLogService,
|
||||
voiceRoomStore,
|
||||
liveKitService,
|
||||
inviteRepository,
|
||||
webhookRepository,
|
||||
limitConfigService,
|
||||
undefined,
|
||||
);
|
||||
const guildService = new GuildService(
|
||||
guildRepository,
|
||||
channelRepository,
|
||||
inviteRepository,
|
||||
channelService,
|
||||
userCacheService,
|
||||
gatewayService,
|
||||
entityAssetService,
|
||||
avatarService,
|
||||
assetDeletionQueue,
|
||||
userRepository,
|
||||
mediaService,
|
||||
cacheService,
|
||||
snowflakeService,
|
||||
rateLimitService,
|
||||
workerService,
|
||||
webhookRepository,
|
||||
guildAuditLogService,
|
||||
limitConfigService,
|
||||
undefined,
|
||||
);
|
||||
const inviteService = new InviteService(
|
||||
inviteRepository,
|
||||
guildService,
|
||||
channelService,
|
||||
gatewayService,
|
||||
guildAuditLogService,
|
||||
userRepository,
|
||||
packRepository,
|
||||
packService,
|
||||
limitConfigService,
|
||||
);
|
||||
|
||||
let stripe: Stripe | null = null;
|
||||
if (Config.stripe.enabled && Config.stripe.secretKey) {
|
||||
stripe = new Stripe(Config.stripe.secretKey, {
|
||||
apiVersion: '2026-01-28.clover',
|
||||
httpClient: Config.dev.testModeEnabled ? Stripe.createFetchHttpClient() : undefined,
|
||||
});
|
||||
Logger.info('Stripe initialized');
|
||||
}
|
||||
|
||||
Logger.info('Worker dependencies initialized successfully');
|
||||
|
||||
return {
|
||||
kvClient,
|
||||
snowflakeService,
|
||||
limitConfigService,
|
||||
userRepository,
|
||||
channelRepository,
|
||||
guildRepository,
|
||||
favoriteMemeRepository,
|
||||
applicationRepository,
|
||||
oauth2TokenRepository,
|
||||
readStateRepository,
|
||||
adminRepository,
|
||||
reportRepository,
|
||||
paymentRepository,
|
||||
userHarvestRepository,
|
||||
adminArchiveRepository,
|
||||
systemDmJobRepository,
|
||||
voiceRepository,
|
||||
connectionRepository,
|
||||
connectionService,
|
||||
cacheService,
|
||||
userCacheService,
|
||||
storageService,
|
||||
assetDeletionQueue,
|
||||
purgeQueue,
|
||||
gatewayService,
|
||||
mediaService,
|
||||
discriminatorService,
|
||||
avatarService,
|
||||
virusScanService,
|
||||
rateLimitService,
|
||||
emailService,
|
||||
inviteService,
|
||||
workerService,
|
||||
unfurlerService,
|
||||
embedService,
|
||||
readStateService,
|
||||
userPermissionUtils,
|
||||
activityTracker,
|
||||
deletionQueueService,
|
||||
bulkMessageDeletionQueueService,
|
||||
deletionEligibilityService,
|
||||
voiceRoomStore,
|
||||
liveKitService,
|
||||
voiceTopology,
|
||||
channelService,
|
||||
guildAuditLogService,
|
||||
contactChangeLogService,
|
||||
csamEvidenceRetentionService,
|
||||
stripe,
|
||||
csamScanJobService,
|
||||
};
|
||||
}
|
||||
|
||||
export async function shutdownWorkerDependencies(_deps: WorkerDependencies): Promise<void> {
|
||||
Logger.info('Shutting down worker dependencies...');
|
||||
Logger.info('Worker dependencies shut down successfully');
|
||||
}
|
||||
Reference in New Issue
Block a user