Saltar a contenido

Service Integration Patterns

Camunda recomienda service tasks como default para integraciones, reservando send/receive tasks para comunicación async con timeouts largos. La elección depende de timing (ms vs segundos) y control de correlation IDs. Workers deben ser reactivos, usar FetchVariables selectivo, y batch activation de 20-50 jobs.

Clasificación de comunicación

Tipo Protocolo Latencia Elemento BPMN
Sync request/response HTTP/REST, gRPC ms Service task
Async req/resp (corto) Message broker ms-sec Service task
Async req/resp (largo) Message broker sec-horas Send + receive tasks
Fire-and-forget AMQP, Kafka N/A Send task
Wait for event Event stream Indefinido Receive task

Service Task como default

Camunda recomienda siempre usar service tasks para sync request/response. Razones:

  1. Built-in timeout handling via job timeout
  2. Retry logic automática (configurable)
  3. Error boundary events para errores de negocio
  4. Correlation ID automática (job key) — no hay que gestionarla
  5. Modelo visual más limpio (un solo elemento)

Para async request/response con latencia corta (ms), el service task también funciona: el worker abre la conexión async, espera la respuesta, y completa el job.

Send + Receive para async largo

Cuando la respuesta tarda segundos o más:

flowchart LR
    Send[Send Task] -->|envía request con correlationId| Wait[wait...]
    Wait -->|recibe response correlacionado por ID| Receive[Receive Task]

Ventajas sobre service task: - User-controlled correlation ID: el usuario genera y controla el ID, no el engine - Timeout explícito: timer boundary event en el receive task - Visualmente claro: el modelo muestra la naturaleza async

Desventajas: - Más elementos en el diagrama - El usuario debe implementar idempotencia y correlación manualmente

Patrones de response handling

Patrón 1: Payload + XOR Gateway

Un solo mensaje de respuesta, routing por contenido:

flowchart LR
    Receive[Receive Task] --> XOR{XOR}
    XOR --> Happy[Happy path]
    XOR --> Error[Error path]

Simple pero requiere inspección del payload.

Patrón 2: Boundary Message Events

Múltiples tipos de mensaje en el mismo punto:

flowchart LR
    Receive[Receive Task] -->|boundary| ErrorH[Error message handler]
    Receive --> NormalH[Normal response handler]

Limitado a ~2 tipos de mensaje.

Patrón 3: Event-Based Gateway

Espera uno de N mensajes posibles:

flowchart LR
    Gateway{Event-Based Gateway} --> A[Message A]
    Gateway --> B[Message B]
    Gateway --> T[Timer timeout]

Poderoso pero complejo de entender para no-técnicos.

Recomendaciones para workers

Arquitectura de deployment

  • Default: una sola aplicación con todos los workers (diferentes clases/funciones por task type)
  • Separar solo si: necesitas escalar un worker específico, o un worker necesita un lenguaje diferente

Data handling

  • FetchVariables: especificar las variables que el worker necesita, no cargar todas
  • Completion: escribir solo variables de resultado, no re-escribir variables de input
  • Razón: previene race conditions en paths paralelos donde dos workers podrían sobrescribir la misma variable

Configuración de polling

Parámetro Recomendación Razón
Batch size 20-50 jobs/request Reduce overhead de red
Long polling Habilitado Evita polling constante en idle
Job streaming Preferido sobre polling Menor latencia en clusters grandes

Threading

Modelo Throughput Cuándo usar
Bloqueante (1 thread) ~10 jobs/sec @ 100ms IO Bajo volumen, lógica simple
Bloqueante (10 threads) ~100 jobs/sec @ 100ms IO Volumen medio
Reactivo (async IO) Bounded by IO Recomendado para IO-heavy

Node.js es inherentemente reactivo (event loop). Java requiere WebFlux/Reactor para ser non-blocking.

Routing de eventos a procesos

Start events

Tipo API Caso de uso
None start event CreateProcessInstance Entry point estándar único
Message start event PublishMessage Múltiples entry points con correlación
Timer start event (automático) Lanzamiento programado
Signal start event BroadcastSignal Múltiples instancias simultáneas

Message correlation

  • Correlation key requerido siempre, incluso para start events
  • Proceso-a-proceso: workers llaman CreateInstanceCommand o PublishMessageCommand
  • Ver concepts/message-correlation para detalles del mecanismo interno

Data handling en procesos

Principios

  • Almacenar el mínimo posible de variables en Camunda
  • Preferir referencias (IDs/UUIDs) sobre payloads completos
  • JSON como formato de serialización (Camunda 8)
  • Datos complejos: UUID en Camunda, datos completos en DB externa

Cuándo almacenar payload directamente

  • El dato solo existe dentro del proceso
  • Comunicación message-oriented lo necesita
  • Caching de performance
  • Tracking histórico requerido
  • No existe un "leading system" para ese dato

Implicaciones para el MVP

  1. Service task como patrón principal: el job worker pattern ya lo soporta bien
  2. Send + receive: implementar message start events y intermediate catch events — cubre la mayoría de casos async
  3. Workers reactivos: diseñar el SDK con async/await desde el inicio
  4. FetchVariables: implementar filtro de variables en la API de activation — reduce tráfico significativamente
  5. Batch activation: soportar en la API REST de jobs
  6. Variable minimalism: documentar como best practice, no enforced por el engine