- MaintenanceService (@Cron daily 4:00): ретенция track_plays >180д чанками по 20k (без ретенции таблица растёт ~100k строк/сутки) + прун осиротевших треков (без проигрываний/лайков/обложки, >30д). Сейчас удаляет 0 (данным 4 дня) — только ограничивает будущий рост. ВНИМАНИЕ: 180д ограничивает и чарт period=all. - getAllNowPlaying: select-проекция (stationId+name) вместо include station:true — не тянем всю строку Station (streamUrl, tags[], даты) на каждый ряд now_playing. - PrismaService: connection_limit=20 в URL идемпотентно (дефолт ~5 мал под ~16 конкурентных поллеров).
35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
||
import { PrismaClient } from '@prisma/client';
|
||
|
||
/**
|
||
* Добавляет connection_limit в URL, если он не задан явно. По умолчанию Prisma
|
||
* берёт num_cpu*2+1 (на мелком VPS ~5), а у нас ~16 now-playing-поллеров + чарты
|
||
* шлют запросы конкурентно — пул из 20 устойчивее под всплески. Идемпотентно:
|
||
* если параметр уже есть в DATABASE_URL — не трогаем.
|
||
*/
|
||
function withConnectionLimit(url?: string): string | undefined {
|
||
if (!url || /[?&]connection_limit=/.test(url)) return url;
|
||
const sep = url.includes('?') ? '&' : '?';
|
||
return `${url}${sep}connection_limit=20`;
|
||
}
|
||
|
||
@Injectable()
|
||
export class PrismaService
|
||
extends PrismaClient
|
||
implements OnModuleInit, OnModuleDestroy
|
||
{
|
||
constructor() {
|
||
super({
|
||
datasources: { db: { url: withConnectionLimit(process.env.DATABASE_URL) } },
|
||
});
|
||
}
|
||
|
||
async onModuleInit() {
|
||
await this.$connect();
|
||
}
|
||
|
||
async onModuleDestroy() {
|
||
await this.$disconnect();
|
||
}
|
||
}
|