Feat : Prio order for auto stream record
All checks were successful
release / build (push) Successful in 27s
release / verify-windows (push) Successful in 1m20s

This commit is contained in:
jeanotx32
2026-08-12 16:01:18 +02:00
parent 96b364bd66
commit eae694d49a
12 changed files with 442 additions and 72 deletions

View File

@@ -1,5 +1,9 @@
import type { StreamState, WatchTarget } from '@stream-control/shared';
import { DEFAULT_WATCH_SETTINGS, fetchStripchatStatus } from '@stream-control/shared';
import {
DEFAULT_WATCH_SETTINGS,
fetchStripchatStatus,
preemptionVerdict,
} from '@stream-control/shared';
import { config } from './config.ts';
import { sessionsRepo, targetsRepo } from './db.ts';
import { hub } from './hub.ts';
@@ -51,7 +55,14 @@ class Watchlist {
if (this.running) return; // un cycle lent ne doit pas s'empiler sur le suivant
this.running = true;
try {
const targets = targetsRepo.list();
// Du plus prioritaire au moins prioritaire : c'est l'ordre de sondage qui
// décide qui tente sa chance en premier sur une VM libre. Sonder au
// hasard laisserait un profil mineur s'en emparer, pour se faire couper
// dans la foulée par son aîné — le résultat serait le même, au prix d'un
// fichier de quelques secondes.
const targets = targetsRepo
.list()
.sort((a, b) => b.priority - a.priority || a.username.localeCompare(b.username));
// Séquentiel et espacé : une poignée de profils ne justifie pas de
// marteler l'API en parallèle.
for (const target of targets) {
@@ -162,9 +173,16 @@ class Watchlist {
if (Date.now() - liveSince < config.autoRecordDelayMs) return;
if (!hub.isOnline(target.agentId)) return;
// Une VM déjà occupée n'est jamais préemptée : l'enregistrement en cours
// prime sur celui qu'on allait lancer.
if (hub.statusOf(target.agentId).recording) return;
// VM occupée : par défaut la capture en place l'emporte, sauf si ce profil
// a reçu le droit d'interrompre et le rang pour le faire. Le verdict est
// recalculé par startTargetRecording — le refaire ici évite seulement de
// consommer une des trois tentatives à chaque cycle pour une interruption
// qui restera refusée tant que rien ne change.
if (hub.statusOf(target.agentId).recording) {
const verdict = preemptionVerdict(target, hub.recordingTarget(target.agentId));
if (!verdict.allowed) return;
}
const agentId = target.agentId;
const name = target.label ?? target.username;