79 lines
1.8 KiB
TypeScript
79 lines
1.8 KiB
TypeScript
import {
|
|
INestApplication,
|
|
Injectable,
|
|
Logger,
|
|
OnModuleInit,
|
|
} from '@nestjs/common';
|
|
|
|
import { PrismaClient } from '@prisma/client';
|
|
|
|
@Injectable()
|
|
export class PrismaService extends PrismaClient implements OnModuleInit {
|
|
private readonly logger = new Logger(PrismaService.name);
|
|
constructor() {
|
|
super({
|
|
log: [
|
|
{
|
|
emit: 'stdout',
|
|
level: 'query',
|
|
},
|
|
{
|
|
emit: 'stdout',
|
|
level: 'error',
|
|
},
|
|
{
|
|
emit: 'stdout',
|
|
level: 'info',
|
|
},
|
|
{
|
|
emit: 'stdout',
|
|
level: 'warn',
|
|
},
|
|
],
|
|
errorFormat: 'pretty',
|
|
transactionOptions: {
|
|
maxWait: 30 * 1000,
|
|
timeout: 60 * 1000,
|
|
},
|
|
});
|
|
}
|
|
|
|
async onModuleInit() {
|
|
this.logger.log('Try to connect database...');
|
|
|
|
const maxRetry = parseInt(process.env.PRISMA_MAX_RETRY as string) ?? 3;
|
|
const retryDelay = 10000;
|
|
|
|
for (let attempt = 1; attempt <= maxRetry; attempt++) {
|
|
try {
|
|
await this.$connect();
|
|
this.logger.log('Connected.');
|
|
return;
|
|
} catch (error) {
|
|
if (attempt < maxRetry) {
|
|
this.logger.warn(
|
|
`Connection attempt ${attempt} failed. Retrying in ${retryDelay}ms...`,
|
|
);
|
|
await this.delay(retryDelay);
|
|
} else {
|
|
this.logger.error(
|
|
`Failed to connect to the database after ${maxRetry} attempts.`,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private delay(ms: number): Promise<void> {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
|
|
async enableShutdownHooks(app: INestApplication) {
|
|
this.$on('beforeExit' as never, async () => {
|
|
this.logger.log('Wait for application closing...');
|
|
await app.close();
|
|
});
|
|
}
|
|
}
|