TIMER_TASK — Espera por Prazo no Fluxo Principal
Pense no forno com timer. Você põe o assado, gira o botão para 40 minutos e vai fazer outra coisa. O forno não "faz" nada nesse tempo — ele só marca a passagem do tempo e avisa quando acabou. Só então você volta e executa o próximo passo (tirar o assado). Onde a analogia quebra: o timer do forno apita e para; um
TIMER_TASKnão apita — quando o prazo vence, o fluxo simplesmente continua sozinho pelo próximo nó.
Um TIMER_TASK modela "aguarde até um prazo, depois continue" como um passo do fluxo principal
— não como um evento de borda anexado a outra tarefa. É a contraparte do
BOUNDARY_INTERRUPTIVE_TIMER
para quando o prazo não interrompe nada: ele é o próximo passo. "Aguardar uma janela de
compensação antes de efetivar a conta", "aguardar até o início do próximo dia útil antes de
prosseguir".
No fio de abertura de conta, o encaixe é uma quarentena regulatória: depois de pedir a criação da conta ao core bancário, o processo espera uma janela obrigatória antes de dar a conta como ativa — sem depender de nenhum sistema externo, só do relógio.
{
"id": "QUARENTENA_REGULATORIA",
"name": "Quarentena Regulatória",
"type": "TIMER_TASK",
"providerType": "STATIC",
"staticValue": "PT48H",
"outgoing": [ { "targetNodeId": "AGUARDAR_CONTA_CRIADA" } ]
}
Ao alcançar QUARENTENA_REGULATORIA, a instância pausa por 48 horas e então segue para
AGUARDAR_CONTA_CRIADA — sem que nada precise correlacionar ou completar uma tarefa externa.
Reaproveita exatamente o mesmo mecanismo de resolução de prazo dos timers de borda
(STATIC/VARIABLE/BEAN), só que como nó de fluxo principal.
Referência de campos
| Campo | Obrigatório? | Descrição |
|---|---|---|
id | Sim | Identificador único. |
name / description | Não | Rótulo e texto livre. |
providerType | Sim | STATIC | VARIABLE | BEAN — mesmas 3 opções dos timers de borda (não inclui TEMPLATE). |
staticValue | Só se STATIC | ISO-8601: duração relativa ("PT1H") ou data absoluta ("2026-12-31T23:59:59Z"). |
providerVariable | Só se VARIABLE | Nome da variável cujo valor (ISO-8601) é o prazo. |
providerBean | Só se BEAN | Bean @Component que implementa DueDateProvider. |
outgoing | Sim (1 entrada usada) | Para onde o fluxo vai depois que o prazo vence. Este nó não ramifica. |
boundaryEventIds | Não | Ver Boundary events. |
Campos que este nó não tem: attachedToRef (não é evento de borda), executor (não invoca
nenhum TaskHandler).
:::tip commitBefore é sempre tratado como true para este nó
Declare-o como quiser (true, false, ou omita) — o motor sempre pausa a execução neste nó. Não
existe "executar um timer de forma síncrona", já que não há como bloquear a chamada pela duração do
prazo.
:::
Estratégias de resolução do prazo (providerType)
providerType | Origem | Campo |
|---|---|---|
STATIC | Valor fixo no JSON | staticValue |
VARIABLE | Variável de processo já calculada | providerVariable |
BEAN | Bean Spring DueDateProvider | providerBean |
O valor resolvido aceita indistintamente uma duração ISO-8601 ("PT1H", somada ao instante em
que o nó foi alcançado) ou uma data absoluta ISO-8601 ("2026-12-25T20:00:00Z"). O motor tenta
interpretar como data absoluta primeiro e, se falhar, como duração — não é preciso declarar o
formato.
Exemplo com BEAN
Uma quarentena que é mais curta para cliente VIP:
package com.empresa.processo.prazos;
import io.kikwiflow.execution.api.context.EvaluationContext;
import io.kikwiflow.execution.api.duedate.DueDateProvider;
import org.springframework.stereotype.Component;
@Component("quarentenaDueDateProvider")
public class QuarentenaDueDateProvider implements DueDateProvider {
@Override
public String resolve(EvaluationContext execution) {
boolean vip = execution.getVariableValue("clienteVip")
.map(v -> Boolean.parseBoolean(v.toString()))
.orElse(false);
return vip ? "PT4H" : "PT48H"; // duração ISO-8601 relativa ao instante de chegada no nó
}
}
{
"id": "QUARENTENA_REGULATORIA",
"type": "TIMER_TASK",
"providerType": "BEAN",
"providerBean": "quarentenaDueDateProvider",
"outgoing": [ { "targetNodeId": "AGUARDAR_CONTA_CRIADA" } ]
}
O que acontece ao disparar
- Ao alcançar o
TIMER_TASK, a instância pausa — ele vira uma tarefa pendente aguardando o prazo (o mesmo mecanismo de polling que resolve timers de borda). - Quando o prazo vence, o fluxo continua pelo
outgoingdeste nó — nenhumTaskHandleré chamado no disparo. O nó só marca a passagem do tempo. - Para executar lógica de negócio depois do prazo, coloque um
EXECUTABLE_TASKnooutgoing.
Boundary events
TIMER_TASK aceita boundaryEventIds. Cada tipo de nó pai aceita seu próprio subconjunto; em
TIMER_TASK:
| Tipo | Efeito |
|---|---|
BOUNDARY_INTERRUPTIVE_TIMER | Um segundo prazo em paralelo; se vencer primeiro, cancela a espera e desvia pela saída do boundary — "espera até X, mas nunca mais que Y". |
BOUNDARY_NON_INTERRUPTIVE_TIMER | Recorre (ping periódico) enquanto o TIMER_TASK segue esperando, sem cancelá-lo. |
BOUNDARY_INTERRUPTIVE_CATCH_EVENT | Cancela a espera via correlação externa antes do prazo — ver BOUNDARY_INTERRUPTIVE_CATCH_EVENT. |
BOUNDARY_ERROR_HANDLER não é suportado — não há try/catch síncrono a resolver, já que nenhum
handler roda.
Limitações conhecidas
- Sem validação, no momento da implantação, do
providerBean. UmproviderType: BEANcomproviderBeaninexistente é implantado normalmente e só falha quando a instância alcança o nó.
Validações
Ao alcançar o nó (é quando o prazo é resolvido): providerType: VARIABLE com variável ausente/
null → IllegalArgumentException; BEAN sem providerBean → IllegalArgumentException; BEAN
sem bean DueDateProvider registrado → BadImplementationException; valor final resolvido nulo/
vazio ou que não é data nem duração ISO-8601 válida → IllegalArgumentException.
Quando usar / quando não usar
| Se você precisa de... | Use |
|---|---|
| Um prazo que é o próprio próximo passo do fluxo principal | TIMER_TASK (este nó) |
| Um prazo que cancela outra tarefa em andamento | BOUNDARY_INTERRUPTIVE_TIMER anexado a essa tarefa |
| Um prazo que dispara um efeito colateral em paralelo, sem cancelar nem ser o próximo passo | BOUNDARY_NON_INTERRUPTIVE_TIMER |
| Um prazo que pode ser cancelado por correlação externa antes de vencer | BOUNDARY_INTERRUPTIVE_CATCH_EVENT anexado a este TIMER_TASK |
| Aguardar uma correlação externa em vez de um prazo, como próximo passo | EVENT_CATCHER |
Próximo passo
Continue para CALL_ACTIVITY_COORDINATOR — Subprocessos.