perf(backend): ретенция track_plays, прун сирот-треков, проекция now-playing, пул БД

- 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
  конкурентных поллеров).
This commit is contained in:
nk
2026-06-06 17:08:36 +03:00
parent 944ec63df0
commit 4aa3b55b5e
4 changed files with 115 additions and 2 deletions

View File

@@ -1,11 +1,29 @@
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();
}