feat(GOV-009): 建立后端契约与健康检查
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import Redis from 'ioredis';
|
||||
import type { OnModuleDestroy } from '@nestjs/common';
|
||||
|
||||
import type { DependencyHealthDto } from '../../http-contracts/src/health.dto';
|
||||
import type { RedisRuntimeConfig } from '../../config/src/runtime-config';
|
||||
|
||||
interface RedisPingPort {
|
||||
status: string;
|
||||
connect(): Promise<void>;
|
||||
ping(): Promise<string>;
|
||||
quit(): Promise<unknown>;
|
||||
}
|
||||
|
||||
export class RedisHealthClient implements OnModuleDestroy {
|
||||
constructor(private readonly client: RedisPingPort) {}
|
||||
|
||||
async check(): Promise<DependencyHealthDto> {
|
||||
if (
|
||||
this.client.status === 'wait' ||
|
||||
this.client.status === 'end' ||
|
||||
this.client.status === 'close'
|
||||
) {
|
||||
await this.client.connect();
|
||||
}
|
||||
const response = await this.client.ping();
|
||||
if (response !== 'PONG') throw new Error('Redis PING 未返回 PONG');
|
||||
return { status: 'healthy', detail: 'PONG' };
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
if (
|
||||
this.client.status !== 'wait' &&
|
||||
this.client.status !== 'end' &&
|
||||
this.client.status !== 'close'
|
||||
) {
|
||||
await this.client.quit();
|
||||
}
|
||||
}
|
||||
|
||||
async onModuleDestroy(): Promise<void> {
|
||||
await this.close();
|
||||
}
|
||||
}
|
||||
|
||||
export function createRedisHealthClient(config: RedisRuntimeConfig): RedisHealthClient {
|
||||
const client = new Redis({
|
||||
host: config.host,
|
||||
port: config.port,
|
||||
username: config.username || undefined,
|
||||
password: config.password || undefined,
|
||||
db: config.database,
|
||||
tls: config.tls ? {} : undefined,
|
||||
lazyConnect: true,
|
||||
enableOfflineQueue: false,
|
||||
maxRetriesPerRequest: 0,
|
||||
});
|
||||
return new RedisHealthClient(client);
|
||||
}
|
||||
Reference in New Issue
Block a user