33800 Docs

← Retour

AI Orchestrator - Phase 3 : Système de Queue

Date: 17/01/2026 18:00 Status: IMPLEMENTE (17/01/2026 18:25) Priorité: HAUTE

Objectif

Implémenter un système de queue pour gérer les requêtes IA de manière asynchrone en utilisant l'infrastructure existante :

Infrastructure Existante Utilisée

┌─────────────────────────────────────────────────────────────────────────────┐
│  INFRASTRUCTURE EXISTANTE (prod-portainer 192.168.1.12)                     │
│                                                                              │
│  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐          │
│  │ supabase-db-prod │  │   redis-prod     │  │      Loki        │          │
│  │   PostgreSQL     │  │    Queue Jobs    │  │   Logs (30j)     │          │
│  │     :5433        │  │     :6379        │  │     :3100        │          │
│  └──────────────────┘  └──────────────────┘  └──────────────────┘          │
│                                                    │                        │
│                                                    ▼                        │
│                                            ┌──────────────────┐            │
│                                            │    O2switch      │            │
│                                            │  Archive (90j)   │            │
│                                            │  (sync 3h cron)  │            │
│                                            └──────────────────┘            │
│                                                                              │
│  ┌──────────────────────────────────────────────────────────────┐          │
│  │                    stock_8to (via NFS)                        │          │
│  │  /mnt/stock_8to/33800-stack/ai-data/jobs/                    │          │
│  │  - inputs/   (images, audio uploadés)                        │          │
│  │  - outputs/  (fichiers générés)                              │          │
│  │  (backup horaire → stock_36to)                               │          │
│  └──────────────────────────────────────────────────────────────┘          │
└─────────────────────────────────────────────────────────────────────────────┘

Architecture Phase 3

┌─────────────────────────────────────────────────────────────────────────────┐
│                        AI ORCHESTRATOR PHASE 3                               │
│                                                                              │
│  Client (IP autorisée)                                                       │
│       │  POST /api/jobs                                                      │
│       ▼                                                                      │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  AI Orchestrator API (FastAPI :5501)                                │   │
│  │                                                                      │   │
│  │  1. Valide input                                                    │   │
│  │  2. Sauvegarde fichiers → stock_8to/ai-data/inputs/                │   │
│  │  3. INSERT job → Supabase PostgreSQL                               │   │
│  │  4. LPUSH job → Redis queue                                        │   │
│  │  5. Return job_id                                                  │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                         │                                                    │
│                         ▼                                                    │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  Worker (dans même container, asyncio)                              │   │
│  │                                                                      │   │
│  │  Loop:                                                              │   │
│  │    1. BRPOP Redis queue                                            │   │
│  │    2. UPDATE job status=running → Supabase                         │   │
│  │    3. Switch tool si nécessaire (via SSH win11)                    │   │
│  │    4. Execute job (API Gradio)                                     │   │
│  │    5. Save output → stock_8to/ai-data/outputs/                     │   │
│  │    6. UPDATE job status=completed → Supabase                       │   │
│  │    7. Log → Loki                                                   │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                         │                                                    │
│                         ▼                                                    │
│               ┌─────────────────┐                                           │
│               │   Win11 GPU     │                                           │
│               │ (192.168.1.30)  │                                           │
│               │  Bark/Music/    │                                           │
│               │  ComfyUI/etc    │                                           │
│               └─────────────────┘                                           │
│                                                                              │
│  Dashboard (O2switch)                                                        │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  ai-jobs.html                                                       │   │
│  │  - Fetch /api/queue (stats)                                        │   │
│  │  - Fetch /api/jobs (history)                                       │   │
│  │  - Via collect.sh (cron horaire existant)                          │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────────┘

Schéma Base de Données (Supabase)

Se connecter à Supabase Studio : http://192.168.1.12:8201

Table ai_jobs

-- Créer dans Supabase via Studio ou API
CREATE TABLE ai_jobs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Identification
    tool_id VARCHAR(50) NOT NULL,           -- bark, musicgen, comfyui, etc.
    job_type VARCHAR(50) NOT NULL,          -- tts, music, image, video

    -- Status
    status VARCHAR(20) NOT NULL DEFAULT 'pending',
    priority INTEGER DEFAULT 0,              -- -1=low, 0=normal, 1=high

    -- Timing
    created_at TIMESTAMPTZ DEFAULT NOW(),
    started_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,

    -- Input (JSONB pour flexibilité)
    input_params JSONB NOT NULL,
    input_files TEXT[],                     -- Chemins relatifs dans ai-data/inputs/

    -- Output
    output_result JSONB,
    output_files TEXT[],                    -- Chemins relatifs dans ai-data/outputs/

    -- Metrics
    processing_time_ms INTEGER,
    vram_used_mb INTEGER,

    -- Error
    error_message TEXT,
    retry_count INTEGER DEFAULT 0
);

-- Index pour requêtes dashboard
CREATE INDEX idx_ai_jobs_status ON ai_jobs(status);
CREATE INDEX idx_ai_jobs_created ON ai_jobs(created_at DESC);

Structure Redis Queue

# Queues (FIFO avec priorité)
ai:queue:high     # Jobs prioritaires
ai:queue:normal   # Jobs normaux
ai:queue:low      # Jobs batch

# État
ai:current_job    # Job ID en cours (pour dashboard)
ai:current_tool   # Outil actif sur win11

Format message queue

{
    "job_id": "uuid",
    "tool_id": "bark",
    "priority": 0
}

Les détails complets sont dans Supabase (pas dupliqués dans Redis).

Structure Fichiers (stock_8to)

/stock_8to/33800-stack/ai-data/
├── inputs/
│   └── {job_id}/
│       ├── source.jpg
│       └── audio.wav
├── outputs/
│   └── {job_id}/
│       ├── result.wav
│       └── result.png
└── temp/
    └── (fichiers temporaires, nettoyés quotidiennement)

API Endpoints (ajouts à main.py)

# === JOBS API ===

@app.post("/api/jobs")
async def create_job(job: JobCreate):
    """Créer un nouveau job dans la queue"""
    # 1. Sauvegarder fichiers input si présents
    # 2. INSERT dans Supabase
    # 3. LPUSH dans Redis queue
    # 4. Return job_id + position

@app.get("/api/jobs")
async def list_jobs(status: str = None, limit: int = 50):
    """Lister les jobs (pour dashboard)"""
    # SELECT depuis Supabase avec filtres

@app.get("/api/jobs/{job_id}")
async def get_job(job_id: str):
    """Status détaillé d'un job"""

@app.delete("/api/jobs/{job_id}")
async def cancel_job(job_id: str):
    """Annuler un job pending"""

@app.get("/api/jobs/{job_id}/output/{filename}")
async def download_output(job_id: str, filename: str):
    """Télécharger fichier output"""
    # Sert depuis stock_8to/ai-data/outputs/{job_id}/

# === QUEUE API ===

@app.get("/api/queue")
async def queue_status():
    """Stats queue pour dashboard"""
    return {
        "pending": redis.llen("ai:queue:*"),
        "current_job": redis.get("ai:current_job"),
        "current_tool": redis.get("ai:current_tool")
    }

Dashboard Integration

Nouveau script: generate.d/20-ai-jobs.sh

#!/bin/bash
# Génère ai-jobs.html avec stats depuis l'API

STATS=$(curl -s http://192.168.1.12:5501/api/queue)
JOBS=$(curl -s "http://192.168.1.12:5501/api/jobs?limit=50")

# Générer HTML avec les données...

Ajout navigation (01-index.sh)

<a href="ai-jobs.html">AI Jobs</a>

Logging (Loki)

Le container ai-orchestrator envoie déjà ses logs à Loki (docker logging driver). Ajouter des logs structurés pour les jobs :

import logging
logger = logging.getLogger("ai-orchestrator")

# Pour chaque job
logger.info("job_started", extra={
    "job_id": job_id,
    "tool_id": tool_id,
    "job_type": job_type
})

logger.info("job_completed", extra={
    "job_id": job_id,
    "processing_time_ms": elapsed,
    "vram_used_mb": vram
})

Requête Grafana :

{container="ai-orchestrator"} |= "job_"

Plan d'Implémentation

Étape 1: Structure fichiers (15 min)

mkdir -p /stock_8to/33800-stack/ai-data/{inputs,outputs,temp}

Étape 2: Table Supabase (15 min)

Étape 3: API endpoints (2h)

Étape 4: Worker loop (2h)

Étape 5: Dashboard (1h)

Étape 6: Tests (1h)

Estimation Totale: ~6h

(Réduit de 10h car utilisation infra existante)

Connexions Services

Service Host Port Credentials
PostgreSQL 192.168.1.12 5433 Voir Supabase config
Redis 192.168.1.12 6379 Pas d'auth
stock_8to /mnt/stock_8to NFS Monté sur prod-portainer
Loki 192.168.1.12 3100 Docker logging driver

Sécurité


Validation requise avant implémentation