CAPÍTULO 6 · Los datos empiezan a llegar
Decidir una acción y conseguir que ocurra son trabajos distintos
La plataforma puede decidir que debe avisar sobre una alarma y guardar esa decisión correctamente. Aun así, el sistema externo encargado de recibir el aviso puede no estar disponible. Si atamos toda la operación a esa llamada, la respuesta al dispositivo o al usuario dependerá de un componente que puede tardar o fallar.
Introducimos tareas y, cuando se requiere conservar la intención de entrega, una outbox. El cambio de negocio y el registro de lo que debe enviarse se coordinan; otro proceso atiende el efecto externo y sus reintentos. La idempotencia vuelve a ser importante porque repetir un intento no debería generar consecuencias descontroladas.
Con esta separación el sistema puede seguir atendiendo trabajo mientras gestiona las entregas pendientes. Entretanto, los datos continúan acumulándose. Lo que al principio cabía en una pantalla pronto exige otra decisión: cómo consultar un período amplio y representarlo sin descargar ni dibujar cada registro existente.
Leer esta parte dentro del relato completo →DEL RELATO A LA PRÁCTICA
Vamos a desarrollar esta decisión con su mapa, explicación, código y ejercicio.
MIRA · CONECTA · COMPRENDE
Dos trabajos unidos por un evento
Las flechas resumen el recorrido conceptual. Los controles y dependencias se detallan debajo.
Selecciona una pieza para destacar su responsabilidad.
Leer la explicación del mapa
- Servicio. Decide cambio de negocio
- Commit + outbox. Persiste estado y trabajo
- Worker. Procesa trabajo pendiente
- Efecto. Notifica con control de reintento
01 / EL PROBLEMA
¿Para qué sirve?
SMTP lento puede bloquear la ingesta. Publicar un mensaje antes de confirmar la base de datos también puede anunciar una operación que se revierte.
02 / COMPRENDER
El concepto, explicado
transaction.on_commit difiere un efecto hasta confirmar, pero no lo vuelve durable: el proceso puede caer justo después del commit.
Outbox guarda la intención de entrega en la misma transacción del negocio. Un worker reclama eventos, entrega y registra resultado, con reintentos e idempotencia.
03 / CONSTRUIR
Implementación paso a paso
- Persiste lectura y evento outbox juntos.
- Reclama eventos sin competencia entre workers.
- Entrega fuera de la transacción de negocio.
- Registra intentos y usa una clave de entrega.
04 / APLICAR
Ejemplo en SensorHub
# Esquema de servicio; OutboxEvent debe ser un modelo propio.
from django.db import transaction
@transaction.atomic
def persist_alarm(*, sensor, reading):
alarm = Alarm.objects.create(sensor=sensor, reading=reading)
OutboxEvent.objects.create(
key=f"alarm:{alarm.pk}",
kind="send_alarm",
payload={"alarm_id": str(alarm.pk)},
)
return alarm
# Un worker entrega y actualiza el evento fuera de esta operación HTTP.Cómo leer el ejemplo
- La fila outbox permanece aunque la petición o proceso terminen.
- Un worker puede reintentar después de reiniciar.
- Entrega exactamente una vez no se obtiene automáticamente: considera duplicados y deduplicación en el destino.
Error habitual
Un correo enviado antes de marcar delivered puede repetirse tras una caída. Diseña tolerancia a reentrega.
05 / PRACTICAR
Tu turno
Apaga el worker después de guardar la alarma y vuelve a iniciarlo.
Ver solución orientativa
El evento sigue pendiente y puede entregarse. La lectura no depende de que SMTP estuviera disponible al recibirla.
06 / VERIFICAR
Cómo sabes que funciona
- La ingesta no espera la latencia del correo.
- Los fallos de entrega tienen estado y número de intentos.
CONTINUAR LA EXPERIENCIA
El siguiente paso del recorrido:
Históricos, filtros y decimación →Continuar en modo relato