2023-07-27 05:31:52 +00:00
|
|
|
/*
|
2024-02-12 02:37:45 +00:00
|
|
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
2023-07-27 05:31:52 +00:00
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2022-09-17 18:27:08 +00:00
|
|
|
import { Global, Inject, Module } from '@nestjs/common';
|
2023-04-14 04:50:05 +00:00
|
|
|
import * as Redis from 'ioredis';
|
2022-09-17 18:27:08 +00:00
|
|
|
import { DataSource } from 'typeorm';
|
2023-05-04 23:52:14 +00:00
|
|
|
import { MeiliSearch } from 'meilisearch';
|
2022-09-17 18:27:08 +00:00
|
|
|
import { DI } from './di-symbols.js';
|
2023-05-24 00:59:30 +00:00
|
|
|
import { Config, loadConfig } from './config.js';
|
2023-02-07 10:50:38 +00:00
|
|
|
import { createPostgresDataSource } from './postgres.js';
|
2022-12-08 08:19:37 +00:00
|
|
|
import { RepositoryModule } from './models/RepositoryModule.js';
|
2024-01-08 03:28:13 +00:00
|
|
|
import { allSettled } from './misc/promise-tracker.js';
|
2022-09-17 18:27:08 +00:00
|
|
|
import type { Provider, OnApplicationShutdown } from '@nestjs/common';
|
|
|
|
|
|
|
|
const $config: Provider = {
|
|
|
|
provide: DI.config,
|
2023-04-07 02:20:14 +00:00
|
|
|
useValue: loadConfig(),
|
2022-09-17 18:27:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const $db: Provider = {
|
|
|
|
provide: DI.db,
|
2022-09-21 20:11:26 +00:00
|
|
|
useFactory: async (config) => {
|
2023-02-07 10:50:38 +00:00
|
|
|
const db = createPostgresDataSource(config);
|
2022-09-17 18:27:08 +00:00
|
|
|
return await db.initialize();
|
|
|
|
},
|
2022-09-21 20:11:26 +00:00
|
|
|
inject: [DI.config],
|
2022-09-17 18:27:08 +00:00
|
|
|
};
|
|
|
|
|
2023-05-04 23:52:14 +00:00
|
|
|
const $meilisearch: Provider = {
|
|
|
|
provide: DI.meilisearch,
|
2023-05-24 00:59:30 +00:00
|
|
|
useFactory: (config: Config) => {
|
2023-05-04 23:52:14 +00:00
|
|
|
if (config.meilisearch) {
|
|
|
|
return new MeiliSearch({
|
2024-01-08 03:28:13 +00:00
|
|
|
host: `${config.meilisearch.ssl ? 'https' : 'http'}://${config.meilisearch.host}:${config.meilisearch.port}`,
|
2023-05-04 23:52:14 +00:00
|
|
|
apiKey: config.meilisearch.apiKey,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
inject: [DI.config],
|
|
|
|
};
|
|
|
|
|
2022-09-17 18:27:08 +00:00
|
|
|
const $redis: Provider = {
|
|
|
|
provide: DI.redis,
|
2023-05-24 00:59:30 +00:00
|
|
|
useFactory: (config: Config) => {
|
2023-07-20 10:50:31 +00:00
|
|
|
return new Redis.Redis(config.redis);
|
2022-09-17 18:27:08 +00:00
|
|
|
},
|
2022-09-21 20:11:26 +00:00
|
|
|
inject: [DI.config],
|
2022-09-17 18:27:08 +00:00
|
|
|
};
|
|
|
|
|
2023-04-09 08:09:27 +00:00
|
|
|
const $redisForPub: Provider = {
|
|
|
|
provide: DI.redisForPub,
|
2023-05-24 00:59:30 +00:00
|
|
|
useFactory: (config: Config) => {
|
2023-07-20 10:50:31 +00:00
|
|
|
const redis = new Redis.Redis(config.redisForPubsub);
|
2023-04-09 08:09:27 +00:00
|
|
|
return redis;
|
|
|
|
},
|
|
|
|
inject: [DI.config],
|
|
|
|
};
|
|
|
|
|
|
|
|
const $redisForSub: Provider = {
|
|
|
|
provide: DI.redisForSub,
|
2023-05-24 00:59:30 +00:00
|
|
|
useFactory: (config: Config) => {
|
2023-07-20 10:50:31 +00:00
|
|
|
const redis = new Redis.Redis(config.redisForPubsub);
|
2023-04-07 02:20:14 +00:00
|
|
|
redis.subscribe(config.host);
|
|
|
|
return redis;
|
2022-09-17 18:27:08 +00:00
|
|
|
},
|
2022-09-21 20:11:26 +00:00
|
|
|
inject: [DI.config],
|
2022-09-17 18:27:08 +00:00
|
|
|
};
|
|
|
|
|
2023-10-03 11:26:11 +00:00
|
|
|
const $redisForTimelines: Provider = {
|
|
|
|
provide: DI.redisForTimelines,
|
|
|
|
useFactory: (config: Config) => {
|
|
|
|
return new Redis.Redis(config.redisForTimelines);
|
|
|
|
},
|
|
|
|
inject: [DI.config],
|
|
|
|
};
|
|
|
|
|
2022-09-17 18:27:08 +00:00
|
|
|
@Global()
|
|
|
|
@Module({
|
|
|
|
imports: [RepositoryModule],
|
2023-10-03 11:26:11 +00:00
|
|
|
providers: [$config, $db, $meilisearch, $redis, $redisForPub, $redisForSub, $redisForTimelines],
|
|
|
|
exports: [$config, $db, $meilisearch, $redis, $redisForPub, $redisForSub, $redisForTimelines, RepositoryModule],
|
2022-09-17 18:27:08 +00:00
|
|
|
})
|
|
|
|
export class GlobalModule implements OnApplicationShutdown {
|
|
|
|
constructor(
|
|
|
|
@Inject(DI.db) private db: DataSource,
|
2022-09-20 19:54:21 +00:00
|
|
|
@Inject(DI.redis) private redisClient: Redis.Redis,
|
2023-04-09 08:09:27 +00:00
|
|
|
@Inject(DI.redisForPub) private redisForPub: Redis.Redis,
|
|
|
|
@Inject(DI.redisForSub) private redisForSub: Redis.Redis,
|
2023-10-03 11:26:11 +00:00
|
|
|
@Inject(DI.redisForTimelines) private redisForTimelines: Redis.Redis,
|
2024-01-08 03:28:13 +00:00
|
|
|
) { }
|
2022-09-17 18:27:08 +00:00
|
|
|
|
2023-05-29 04:21:26 +00:00
|
|
|
public async dispose(): Promise<void> {
|
2024-01-08 03:28:13 +00:00
|
|
|
// Wait for all potential DB queries
|
|
|
|
await allSettled();
|
|
|
|
// And then disconnect from DB
|
2022-09-17 18:27:08 +00:00
|
|
|
await Promise.all([
|
|
|
|
this.db.destroy(),
|
|
|
|
this.redisClient.disconnect(),
|
2023-04-09 08:09:27 +00:00
|
|
|
this.redisForPub.disconnect(),
|
|
|
|
this.redisForSub.disconnect(),
|
2023-10-03 11:26:11 +00:00
|
|
|
this.redisForTimelines.disconnect(),
|
2022-09-17 18:27:08 +00:00
|
|
|
]);
|
|
|
|
}
|
2023-05-29 04:21:26 +00:00
|
|
|
|
|
|
|
async onApplicationShutdown(signal: string): Promise<void> {
|
|
|
|
await this.dispose();
|
|
|
|
}
|
2022-09-17 18:27:08 +00:00
|
|
|
}
|