Deployment Pipeline
El deployment en Zeebe es un proceso multi-fase: el cliente envía resources a la partición de deployment (partition 1), donde se transforman (BPMN/DMN/Forms parsing), se validan, se persisten, y luego se distribuyen a todas las demás particiones con dedup y retry automático.
Flujo general¶
flowchart TD
Client[Cliente] --> GW[Gateway]
GW --> P1[Partition 1<br/>DEPLOYMENT_PARTITION]
P1 --> Proc[DeploymentCreateProcessor.processNewCommand]
Proc --> Auth[Authorization check<br/>CREATE on RESOURCE]
Auth --> Trans[DeploymentTransformer.transform]
subgraph Transform
BPMN[Parse BPMN XML --> ExecutableProcess]
DMN[Parse DMN XML --> Decisions + Requirements]
Forms[Parse Forms JSON --> Form metadata]
Val[Validate all resources]
end
Trans --> Transform
Transform --> Keys[Generate keys<br/>processDefinitionKey, etc.]
Keys --> Events[Write CREATED events per resource]
Events --> Dist[Distribute to all other partitions]
Dist --> Subs[Manage start event subscriptions]
DeploymentCreateProcessor¶
Implementa DistributedTypedRecordProcessor<DeploymentRecord>, una interfaz especializada que distingue entre:
processNewCommand(): procesa commands que llegan por primera vez (desde el cliente via Gateway)processDistributedCommand(): procesa commands que llegan distribuidos desde otra partición
Fase 1: Authorization¶
AuthorizationRequest.builder()
.command(command)
.resourceType(AuthorizationResourceType.RESOURCE)
.permissionType(PermissionType.CREATE)
.tenantId(command.getValue().getTenantId())
.newResource()
.build();
Si el check falla, el command se rechaza con el tipo de rejection correspondiente.
Fase 2: Transformation¶
DeploymentTransformer procesa cada resource del deployment:
- BPMN: pasa por el pipeline de 5 pasos (ver concepts/bpmn-execution-model) — XML → BpmnModelInstance → validation → ExecutableProcess → cache
- DMN: parseo via dmn-scala, genera
DecisionRequirementsRecord+DecisionRecordpor cada decisión - Forms: parsea JSON, extrae metadata (formId, formVersion)
- Resources: recursos genéricos sin transformación especial
Para cada resource procesado, se emiten events de creación:
- PROCESS:CREATED
- DECISION:CREATED / DECISION_REQUIREMENTS:CREATED
- FORM:CREATED
- RESOURCE:CREATED
Fase 3: Distribution¶
Después de la transformación exitosa, el deployment se distribuye a todas las demás particiones:
flowchart LR
P1[Partition 1 leader] --> CDB[CommandDistributionBehavior]
CDB -->|DEPLOYMENT:DISTRIBUTE| P2[Partition 2]
CDB -->|DEPLOYMENT:DISTRIBUTE| P3[Partition 3]
CDB -->|DEPLOYMENT:DISTRIBUTE| PN[Partition N]
Cada partición receptora:
1. Verifica dedup: deploymentState.hasStoredDeploymentRecord(key) — si ya existe, ALREADY_EXISTS rejection
2. Procesa y almacena el deployment localmente
3. Gestiona start event subscriptions
4. Envía DEPLOYMENT_DISTRIBUTION:COMPLETE acknowledgment
Fase 4: Start Event Subscription Management¶
StartEventSubscriptionManager.tryReOpenStartEventSubscription() maneja las subscriptions de start events:
- Message start events: crea subscriptions para recibir mensajes que inicien nuevas instancias
- Signal start events: registra para recibir broadcasts de señales
- Timer start events: crea timer instances para triggers periódicos
Cuando se deploya una nueva versión de un proceso, las subscriptions de la versión anterior se cancelan y se crean nuevas.
Retry y redistribution¶
DeploymentRedistributionScheduler es un listener que periódicamente reintenta la distribución de deployments que no fueron acknowledged:
- Revisa el
DeploymentStatepara encontrar distribuciones pendientes - Reenvía
DEPLOYMENT:DISTRIBUTEcommands a las particiones que no respondieron - Esto garantiza eventual consistency incluso si una partición estaba temporalmente no disponible
Error handling¶
El processor maneja dos tipos de errores de forma diferenciada:
| Error | Tipo | Acción |
|---|---|---|
ResourceTransformationFailedException |
BPMN/DMN inválido | INVALID_ARGUMENT rejection |
TimerCreationFailedException |
No se puede crear timer de start event | PROCESSING_ERROR rejection |
En ambos casos, se invalidan los caches para evitar estado inconsistente (si ya se había generado metadata pero no los events).
Implicaciones para simplificación¶
Para un MVP single-partition:
- Eliminar distribution: no hay otras particiones a las que enviar
- Simplificar transformer: solo BPMN (sin DMN, forms, generic resources inicialmente)
- Eliminar dedup check: no hay distributed commands
- Mantener start event subscriptions: esencial para message/timer start events
- Simplificar authorization: RBAC simple en vez del AuthorizationRequest builder
El deployment se reduce a: parse BPMN → validate → store en PostgreSQL → crear subscriptions.