Manejo Robusto de Fallos en Procesos por Lotes con Notificaciones Inteligentes

En el proyecto Reimpact/platform, que facilita diversas operaciones empresariales, la fiabilidad de los procesos asíncronos por lotes es crucial. Para asegurar que las operaciones críticas se completen correctamente y que los usuarios reciban retroalimentación precisa, hemos implementado mejoras significativas en la detección y gestión de fallos en nuestros procesos por lotes.

El desafío principal era proporcionar una visibilidad clara sobre el estado de los lotes, especialmente cuando estos fallan, de manera que el usuario final pueda comprender qué sucedió y tomar acciones correctivas si fuera necesario. Anteriormente, un fallo en un proceso por lotes podría dejar al usuario en la incertidumbre, con un "spinner" de carga que no desaparecía o una falta de notificación clara.

Para abordar esto, hemos desarrollado un sistema que detecta varios escenarios de fallo y reacciona en consecuencia:

  • Fallo Total del Lote: Si todos los trabajos dentro de un lote fallan, el sistema ahora lo detecta explícitamente y transiciona a un estado de error, mostrando una notificación de peligro persistente.
  • Fallos Parciales: Si algunos trabajos fallan, pero no todos, se genera una notificación de advertencia, permitiendo al usuario revisar los resultados y entender que la operación se completó parcialmente.
  • Lote Ausente: Un escenario particular es cuando se detecta un ID de lote en caché, pero el lote real no se encuentra en la base de datos (por ejemplo, si un trabajo falló antes de su procesamiento inicial o si el servicio de Horizon no estaba disponible). En estos casos, se muestra un mensaje de error crítico.
  • Polling Prolongado sin Clave de Caché: Si el sistema está consultando el estado de un lote durante un tiempo prolongado y la clave de caché asociada no se encuentra, esto podría indicar que el servicio de procesamiento de colas (como Laravel Horizon) está inactivo. También se informa al usuario con una notificación de error.

Todas estas detecciones se integran con un sistema de notificaciones en Filament, que muestra alertas visuales claras. Además, en estados de error, se presenta un botón "Recalcular" para facilitar el reintento del proceso.

Este enfoque mejora la experiencia del usuario y la resiliencia de la plataforma al proporcionar diagnósticos y acciones claras en caso de fallos en los procesos asíncronos.

<?php

// Ejemplo conceptual de una función para verificar el estado de un lote
// y determinar el tipo de notificación apropiada en un contexto Laravel/Livewire.

/**
 * Simula la determinación del estado de un lote y la notificación resultante.
 * @param array $batchData Datos simulados del estado del lote.
 * @param bool $isCacheKeyPresent Indica si la clave de caché del lote está presente.
 * @return array Un array con el tipo de notificación, mensaje y persistencia.
 */
function getBatchNotification(array $batchData, bool $isCacheKeyPresent):
{array
    if (!$isCacheKeyPresent) {
        return ['type' => 'danger', 'message' => 'Error: Clave de caché de lote no encontrada. ¿Horizon está activo?', 'persistent' => true];
    }

    if (empty($batchData)) {
        return ['type' => 'danger', 'message' => 'Error: Lote no encontrado en la DB. Fallo temprano.', 'persistent' => true];
    }

    if ($batchData['failedJobs'] > 0 && $batchData['totalJobs'] === $batchData['failedJobs']) {
        return ['type' => 'danger', 'message' => 'Error: Todos los trabajos del lote fallaron.', 'persistent' => true];
    } elseif ($batchData['failedJobs'] > 0) {
        return ['type' => 'warning', 'message' => 'Advertencia: Algunos trabajos del lote fallaron. Revise los resultados.', 'persistent' => false];
    } elseif ($batchData['finished']) {
        return ['type' => 'success', 'message' => 'Éxito: Lote completado correctamente.', 'persistent' => false];
    }

    return ['type' => 'info', 'message' => 'Lote en progreso...', 'persistent' => false];
}

// Uso hipotético:
/*
$batchInfo = ['totalJobs' => 10, 'pendingJobs' => 0, 'failedJobs' => 3, 'finished' => true];
$notification = getBatchNotification($batchInfo, true);
// dispatchBrowserEvent('notify', $notification);
*/
Manejo Robusto de Fallos en Procesos por Lotes con Notificaciones Inteligentes
Gerardo Ruiz

Gerardo Ruiz

Author

Share: