Arquitectura del Sistema
Este documento describe la arquitectura interna de Integration Hub for Moodle (MIH), las responsabilidades de cada componente y las decisiones de diseño detrás de ellos.
Vista General de Alto Nivel
MIH está estructurado alrededor de dos caminos de ejecución independientes pero complementarios:
Mapa de Componentes
Capa Core
| Clase | Namespace | Archivo | Rol |
|---|---|---|---|
mih | local_integrationhub | classes/mih.php | Orquestador principal. Facade/Singleton. API pública para todos los plugins. Coordina resolución de servicios, circuit breaking, selección de transporte, reintentos y logging. |
mih_response | local_integrationhub | classes/mih_response.php | Value object inmutable. Encapsula el resultado de cada petición independientemente del transporte. |
Capa de Servicios
| Clase | Namespace | Archivo | Rol |
|---|---|---|---|
registry | local_integrationhub\service | classes/service/registry.php | Acceso a datos. Operaciones CRUD sobre la tabla local_integrationhub_svc. También inicializa el registro del circuit breaker al crear un servicio. |
circuit_breaker | local_integrationhub\service | classes/service/circuit_breaker.php | Tolerancia a fallos. Rastrea contadores de fallos y gestiona transiciones de estado CLOSED/OPEN/HALFOPEN. |
retry_policy | local_integrationhub\service | classes/service/retry_policy.php | Resiliencia. Ejecuta un callable con reintentos configurables y backoff exponencial. |
Capa de Transporte
| Clase | Namespace | Archivo | Rol |
|---|---|---|---|
contract | local_integrationhub\transport | classes/transport/contract.php | Interfaz. Define el contrato execute() que todos los drivers deben implementar. |
http | local_integrationhub\transport | classes/transport/http.php | Driver REST. Usa cURL nativo de PHP. Soporta GET, POST, PUT, PATCH, DELETE. |
amqp | local_integrationhub\transport | classes/transport/amqp.php | Driver RabbitMQ. Usa php-amqplib. Publica mensajes JSON en exchanges o colas. |
amqp_helper | local_integrationhub\transport | classes/transport/amqp_helper.php | Utilidades AMQP. Centraliza la creación de conexiones (plain y SSL) y la declaración de colas. |
soap | local_integrationhub\transport | classes/transport/soap.php | Driver SOAP. Usa el SoapClient nativo de PHP. |
transport_utils | local_integrationhub\transport | classes/transport/transport_utils.php | Trait. Helpers compartidos para construir arrays success_result y error_result. |
Capa de Eventos
| Clase | Namespace | Archivo | Rol |
|---|---|---|---|
observer | local_integrationhub\event | classes/event/observer.php | Listener universal. Registrado contra \core\event\base para capturar todos los eventos de Moodle. Realiza búsqueda de reglas, deduplicación y encolado de tareas adhoc. |
webhook_received | local_integrationhub\event | classes/event/webhook_received.php | Evento personalizado. Se dispara cuando se recibe un webhook entrante. |
Capa de Tareas
| Clase | Namespace | Archivo | Rol |
|---|---|---|---|
dispatch_event_task | local_integrationhub\task | classes/task/dispatch_event_task.php | Tarea adhoc. Procesa un evento encolado: carga la regla, interpola el template, llama a la API MIH, maneja DLQ en fallo permanente. |
consume_responses_task | local_integrationhub\task | classes/task/consume_responses_task.php | Tarea programada. Se ejecuta cada minuto. Consume mensajes entrantes de colas de respuesta AMQP configuradas. |
Caminos de Ejecución
Camino 1: Llamada Directa desde Plugin (Síncrono)
Este camino es síncrono — el plugin que llama espera por el resultado. Úsalo cuando necesites la respuesta inmediatamente (ej. para validar datos, obtener un ID, o mostrar un resultado al usuario).
Camino 2: Event Bridge (Asíncrono)
Este camino es asíncrono — la acción del usuario completa inmediatamente. La integración ocurre en segundo plano. Úsalo para notificaciones fire-and-forget, webhooks, y streaming de eventos.
Decisiones de Diseño Clave
Patrón Facade (MIH)
mih es estrictamente una fachada sobre la instancia singleton interna. Esto proporciona una API estática limpia (mih::request()) mientras mantiene la testabilidad y la gestión del estado internamente.
Transporte como Patrón Strategy
La capa de transporte usa el patrón Strategy mediante la interfaz contract. La API MIH selecciona el driver correcto en tiempo de ejecución basándose en el campo type del servicio. Agregar un nuevo transporte (ej. gRPC) solo requiere implementar contract y registrarlo en get_transport_driver().
Lógica de Reintentos en MIH API vs. Transport
La lógica de reintentos vive en la API MIH (via retry_policy), no dentro de cada driver de transporte. Esto mantiene los drivers simples y asegura un comportamiento de reintento consistente independientemente del transporte.
Deduplicación via Caché
La deduplicación de eventos usa la caché de aplicación de Moodle (local_integrationhub/event_dedupe). La clave de caché es un hash SHA1 de eventname + objectid + userid + crud. Esto previene que se encolen tareas adhoc duplicadas cuando el mismo evento lógico se dispara múltiples veces.
DLQ Después de 5 Intentos
El sistema de tareas adhoc de Moodle™ tiene su propio mecanismo de reintentos. dispatch_event_task rastrea su propio contador de intentos en custom_data. Después de 5 intentos totales, deja de relanzar la excepción y en su lugar escribe el payload fallido en local_integrationhub_dlq, previniendo bucles infinitos de reintentos.
Auto-purga de Logs
La tabla de logs se purga automáticamente después de cada escritura. El número máximo de entradas es configurable (predeterminado: 500). Esto previene el crecimiento ilimitado de la base de datos en despliegues de alto tráfico.
Relaciones de Base de Datos
Todas las claves foráneas se eliminan en cascada — borrar un servicio limpia todos los registros asociados.