CreaRack-SL

Task Huey compute_integrity_snapshots — automatización diaria del Motor de Integridad

Entidadactivecreado Fri Jul 17#racks#task#huey#celery#scheduling#django

Ubicación

racks/tasks.py (línea ~241)

Task periódica de Huey (job queue de background).

Definición

@db_periodic_task(crontab(hour="4", minute="15"))
@lock_task("rack-integrity-snapshots")
def compute_integrity_snapshots():
    """
    Computa y persiste la foto de integridad plano↔realidad de cada org.
    
    Recolección interna para calibración del gate #202 — no alimenta UI todavía.
    Corre con bypass GUC ('0') + scoping manual ORM, patrón core-0029.
    """
    from core.models import Organization
    from racks.services import integrity
    
    orgs = 0
    rows = 0
    for org in Organization.objects.all():
        try:
            result = integrity.compute_integrity(org)
            rows += integrity.persist_snapshots(org, result)
            orgs += 1
        except Exception as e:
            logger.error(f"Integrity snapshot failed for org {org.id}: {e}")
    logger.info(f"Integrity snapshots: {orgs} orgs, {rows} filas")
    return {"orgs": orgs, "rows": rows}

Semántica

Cuándo Corre

Diariamente a las 04:15 UTC (tras backups nocturnos a las 03:30).

Decoradores:

  • @db_periodic_task(crontab(...)) — registro automático con Huey
  • @lock_task("rack-integrity-snapshots") — solo 1 instancia simultáneamente (evita race conditions)

Qué Hace

  1. Itera todas las Organization (sin filtro)
  2. Para cada org: llama a integrity.compute_integrity(org) (parámetros default: 7 días, 30 min)
  3. Persiste el resultado con integrity.persist_snapshots(org, result)
  4. Registra en logger: org exitosas y total de filas (racks + resúmenes)
  5. Si falla una org: registra error, continúa con la siguiente

Retorno: dict con {"orgs": count, "rows": count}

RLS y Seguridad

La task corre con GUC app.current_org_id = '0' (bypass admin admin) porque:

  1. Huey no tiene request HTTP → no hay middleware que setee GUC automáticamente
  2. El bypass ‘0’ es estándar en tasks de background (ver TenantRLSMiddleware)
  3. Scoping manual ORM: itera Organization.objects.all() explícitamente
  4. Cada snapshot escrito con organization=org fijo → RLS lo aisla automáticamente

Patrón idéntico a purge_deleted_organizations (core/tasks.py) y run_full_backup (racks/tasks.py).

Idempotencia

Llamar 2 veces el mismo día no duplica filas:

  • Constraint único por (org, rack, date) con nulls_distinct=False
  • persist_snapshots() usa update_or_create()
  • 2ª llamada actualiza counts/findings/métricas, no crea nuevas filas

Útil si:

  • La task falla a mitad y se reintenta
  • Un admin corre rack_integrity_probe --org X --save el mismo día
  • El schedule cambia (ejemplo: 04:15 pasa a 06:00 en DST)

Logging

Info (Éxito Normal)

Integrity snapshots: 47 orgs, 204 filas

Significa: procesadas 47 organizaciones, escritas 204 filas (racks + resúmenes).

Error (Org Individual Falla)

Integrity snapshot failed for org 15: [ErrorMessage]

Registra el error pero sigue procesando otras orgs — no interrumpe.

Ejemplos de fallos capturados:

  • Organization.DoesNotExist (data inconsistency)
  • DeviceProfile.MultipleObjectsReturned (datos corruptos)
  • IntegrityError en persistencia (constraints violados)

Requisitos Previos

  1. Huey configurado en settings/
  2. Worker de Huey corriendo (servicio huey en Docker o systemd)
  3. Database accesible desde worker
  4. Migraciones 0014 + 0015 aplicadas (tabla + RLS)
  5. Services/integrity.py presente (código nuevo)

Rendimiento

Orden de complejidad: O(n*m) donde n=orgs, m=dispositivos/org.

Benchmarks (estimados):

  • Org con 1 rack + 40 devices: ~100ms
  • Org con 10 racks + 400 devices: ~1s
  • 47 orgs (escala actual): ~30-45 segundos total

Timeout de Huey: por defecto 10 min (suficiente). Ajustable en settings si es necesario.

Configuración en settings

# config/settings/production.py
HUEY = {
    'huey_class': 'huey.PriorityQueue',
    'name': 'crearack-huey',
    'immediate': False,  # False = async en production
    'utc': True,
    'scheduler_interval': 60,  # poll cada 60 sec para tareas periódicas
    'db_table': 'huey_task',  # tabla de storage
    # ...más config
}

La tarea aparecerá automáticamente en la lista de periódicas de Huey.

Integración con Huey CLI

Listar tareas:

python manage.py huey_status

Verá compute_integrity_snapshots con schedule 04:15 UTC.

Forzar ejecución manual:

python manage.py huey_consumer --immediate  # en dev, corre sincrónico
# → inmediatamente ejecuta todas las periódicas

O desde shell:

from racks.tasks import compute_integrity_snapshots
result = compute_integrity_snapshots()
print(result)  # {"orgs": 47, "rows": 204}

Ejemplos de Query Post-Task

Tras la task, analizar snapshots:

# Snapshots de hoy
today = timezone.localdate()
snapshots = RackIntegritySnapshot.objects.filter(date=today, rack__isnull=False)

# Por org
org = Organization.objects.get(id=1)
org_summary = RackIntegritySnapshot.objects.get(
    organization=org, rack=None, date=today
)
print(f"Org {org.name}: fidelity {org_summary.fidelity_pct}%")

# Racks con fidelidad baja
low_fidelity = snapshots.filter(fidelity_pct__lt=80)
for snap in low_fidelity:
    print(f"{snap.rack.name}: {snap.fidelity_pct}%")

Monitoreo y Alertas (Futuro)

Cuando F2/F3 añadan dashboards:

  1. Degradación de fidelity: si cae >10% día-a-día → alertar
  2. Aumento de undocumented: si >X equipos nuevos/día → revisar
  3. Task falla: Huey registra si compute_integrity_snapshots falla → healthcheck

Hoy, sin UI, solo monitoreamos logs (ver logging arriba).

Relación con Otros Components

compute_integrity_snapshots (task Huey, diaria)
    ↓
    ├─ integrity.compute_integrity(org)  ← quién computa
    │   ├─ Device.objects.filter(rack__organization=org)
    │   ├─ DeviceProfile.objects.filter(organization=org)
    │   └─ MonitoringTarget.objects.filter(organization=org)
    │
    └─ integrity.persist_snapshots(org, result)  ← quién guarda
        └─ RackIntegritySnapshot.objects.update_or_create()
        
rack_integrity_probe (comando, manual)
    ├─ compute_integrity()  ← reutiliza
    └─ persist_snapshots()  ← reutiliza (si --save)

Notas de Operación

  • Timezone: toda la computación en UTC; date es DateField (sin hora)
  • Datos históricos: snapshots se acumulan → base de datos crece ~50 filas/día (47 orgs)
  • Retention: sin política de purga hoy; considerar en F2/F3 si ocupan espacio
  • Frescura de datos: corre a 04:15, datos de “ayer” se persisten (patrón estándar de batch nightly)

Debugging

Si la task falla silenciosamente:

  1. Chequear logs de Huey: docker logs crearack-huey
  2. Verificar DB de Huey: SELECT COUNT(*) FROM huey_task (verificar queue limpia)
  3. Verificar RLS en la tabla: SELECT COUNT(*) FROM racks_rackintegritysnapshot
  4. Ejecutar manualmente en shell para ver el traceback completo

Véase también

  • [[feature—racks—motor-integridad-f1]]
  • [[entity—racks—service—integrity]]
  • [[entity—racks—model—rack-integrity-snapshot]]
  • [[entity—racks—command—rack-integrity-probe]]