> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Como o Streaming Hub funciona

> O caminho que um evento percorre pelo Streaming Hub: ingestão, classificação, deduplicação de consumo único, correspondência de subscriptions, despacho, novas tentativas e dead-letters.

Um evento percorre o Streaming Hub em três etapas. O hub o **ingere** do stream interno, o **compara** com as suas subscriptions e o **despacha** para cada destino correspondente. Esta página percorre cada etapa e as garantias de entrega que saem dela.

## Ingerir eventos do stream

***

O Streaming Hub consome o stream da plataforma como mensagens **CloudEvents 1.0** em **modo de conteúdo binário**. Os atributos de contexto do CloudEvents viajam nos headers do registro Kafka (cada um com o prefixo `ce-`). O corpo do evento é o valor do registro. O hub lê roteamento e identidade dos headers.

O hub assina apenas os **tópicos de fato de aplicação** v3:

```
lerian.streaming.<ce-source>
```

O `ce-source` é um segmento único, em minúsculas e sem pontos. Ele usa letras, dígitos, sublinhados ou hifens. O tópico não carrega sufixo de recurso, de evento nem de major do schema. O hub despacha pelos headers do CloudEvents. O conjunto seguido exclui tópicos de comando (`.commands`) e tópicos de dead-letter (`.dlq`).

Um segundo consumidor lê os tópicos `.dlq` que os produtores gravam. Esse consumidor serve apenas à observabilidade. A gramática do conjunto seguido exclui um `.dlq` final, então um registro de dead-letter nunca vira uma entrega para uma das suas subscriptions. O `GET /admin/dlq` lê esses registros. Veja [observações de dead-letter](https://docs.lerian.studio/pt/platform/streaming-hub/operating-streaming-hub.md).

Cada registro que o hub aceita deve carregar este conjunto de contexto:

| Header | Exigência |
| - | - |
| `ce-specversion` | A versão da especificação CloudEvents. |
| `ce-id` | Um id de evento único. Deve ser um UUIDv7. Ele é a chave de deduplicação e de correlação. Isso aperta o [contrato de envelope compartilhado](https://docs.lerian.studio/pt/reference/events/overview.md), onde o `ce-id` é opaco: o hub põe em quarentena um registro cujo id não seja um UUIDv7, e deduplica ids dentro de um tenant. |
| `ce-source` | O serviço produtor. |
| `ce-type` | O tipo do evento, exatamente `studio.lerian.<source>.<resource>.<event>`; o `<source>` deve ser igual ao `ce-source`. |
| `ce-time` | O timestamp da emissão. |
| `ce-schemaversion` | A versão do schema do payload. |
| `ce-resourcetype` | O segmento de recurso (por exemplo, `account`). |
| `ce-eventtype` | O segmento de evento (por exemplo, `created`). |
| `ce-tenantid` | O tenant dono, e a única fonte de identidade de tenant na ingestão. Um registro sem ele vai para quarentena. |

Para cada registro o hub devolve um de três **vereditos**:

| Veredito | Quando | Resultado |
| - | - | - |
| **Aceitar** | Um evento bem formado com id de tenant não vazio. | Gravado na caixa de entrada de eventos e comparado com as subscriptions desse mesmo tenant. |
| **Descartar** | Um evento de sistema. | Contado e pulado; a posição no stream ainda avança. Nenhum evento é guardado. |
| **Quarentena** | Um evento malformado, ou sem o tenant dele. | Sem nova tentativa. Um registro malformado nunca fica válido em uma reprodução. |

O tenant admitido na ingestão vem apenas do atributo `ce-tenantid` validado que o parser extraiu. A ingestão não tem portão de descarte por lista de tenants. Os eventos guardados apenas correspondem a subscriptions com o mesmo id de tenant.

> [!NOTE]
>
> Três strings parecidas são coisas distintas. Nunca as confunda:
>
> * **`ce-type`** é o tipo CloudEvents qualificado pela origem: `studio.lerian.<source>.<resource>.<event>` (por exemplo, `studio.lerian.lender.loan_application.approved`).
> * **O tópico Kafka** é um tópico de fato v3 por aplicação: `lerian.streaming.<source>` (por exemplo, `lerian.streaming.lender`). Recurso, evento e major do schema não aparecem no tópico.
> * **`X-Lerian-Event-Type`** é a chave `<resource>.<event>` pura em um webhook entregue (`loan_application.approved`). Ela omite o produtor de propósito. Use um `origin` fixo na subscription quando a mesma chave puder vir de mais de uma aplicação.
>
> Veja a [visão geral de streaming de eventos](https://docs.lerian.studio/pt/reference/events/overview.md) para o contrato de fio completo.

## Deduplicação de consumo único

***

O stream interno é pelo menos uma vez, então o mesmo registro pode chegar mais de uma vez. No caminho para a caixa de entrada de eventos, o hub deduplica pelo `ce-id`. Um id duplicado não grava nada e conta como descarte por dedup. O hub grava registros por partição Kafka em uma transação. Ele confirma a posição no stream de uma partição apenas depois que a gravação daquela partição é confirmada. Uma falha em uma partição, portanto, nunca perde nem confirma duas vezes eventos de outra.

## Correspondência de subscriptions

***

A correspondência admite uma subscription apenas quando ela está `enabled` e em `verification_state = active`. Essas são duas condições independentes, e a correspondência exige as duas. Veja [o modelo de subscription](https://docs.lerian.studio/pt/platform/streaming-hub/managing-subscriptions.md).

Um evento que nenhuma subscription quer produz zero entregas. Esse é um resultado correto, não um erro.

## Despachar para os seus destinos

***

Para cada correspondência, o hub cria um job de entrega e o passa a um pool de workers (oito workers por padrão). O destino de uma subscription usa no máximo metade dos workers ao mesmo tempo, então um destino lento deixa o resto para as suas outras subscriptions. Os workers reivindicam jobs vencidos de forma atômica com um lease curto e intercalam entre tenants, então o acúmulo de um único tenant nunca deixa os outros sem vez. Cada worker carrega o payload guardado, descriptografa em memória o signing secret ou a credencial do destino, e faz exatamente uma tentativa de entrega ao sink.

A entrega é **pelo menos uma vez**: o hub pode entregar o mesmo evento mais de uma vez (por novas tentativas ou reentregas depois do reinício de um worker). Veja [Consumir eventos](https://docs.lerian.studio/pt/platform/streaming-hub/consuming-events.md) para o lado do consumidor desse contrato.

## Novas tentativas e backoff

***

Quando uma tentativa falha, o hub agenda a próxima em uma curva de backoff fixa com jitter completo:

```
0 · 5s · 5m · 30m · 2h · 5h · 10h · 10h
```

Um job recebe no máximo oito tentativas. Uma tentativa que começa 24 horas ou mais depois que o hub recebeu o evento é a última do job.

## Dead-letter

***

O hub manda para **dead-letter** um evento que esgota suas novas tentativas. O hub para de tentá-lo e registra o resultado terminal. O hub recupera um job que, em vez disso, derruba um worker no meio da tentativa e nunca registra um resultado. O limite de recuperação é cinco por padrão. O hub então o manda para dead-letter como venenoso, assim um único job tóxico nunca ocupa um worker para sempre.

## Circuit breaker

***

Cada par `(tenant, destination)` tem um circuit breaker. Quando um destino falha repetidamente, o breaker dele abre. Os jobs seguintes para aquele destino esperam sem tentativa, mas a última tentativa de um job ainda pode rodar. Um único endpoint quebrado não queima capacidade de worker nem martela um alvo em dificuldade. O breaker se recupera sozinho assim que o destino volta a ter sucesso.

## Desabilitar automaticamente um destino quebrado

***

O hub desabilita automaticamente um destino que fica quebrado por muito tempo. A desabilitação automática dispara apenas quando o período de falha aberto é os dois:

* **contínuo**: dura pelo menos a janela de falha (120 horas por padrão), e
* **espalhado**: pelo menos 12 horas separam a primeira e a última falha do período.

Os dois portões devem valer, e uma única entrega bem-sucedida limpa o período, então uma oscilação breve nunca acumula rumo ao veredito. Quando a desabilitação automática dispara, ela vira a flag `enabled` da subscription para `false`. Ela nunca toca no `verification_state`. A entrega para (a correspondência exige `enabled`), e o hub registra o motivo.

Você recupera uma subscription desabilitada automaticamente com `POST /v1/subscriptions/:id/verify`, que sonda o destino de novo e, em caso de sucesso, a reabilita no lugar. Veja [recuperar uma subscription desabilitada automaticamente](https://docs.lerian.studio/pt/platform/streaming-hub/managing-subscriptions.md).

## Garantias de ordenação

***

Os produtores particionam o stream por tenant, então os eventos de um tenant normalmente viajam em uma única partição. O hub os guarda nessa ordem e dá a cada um uma sequência de chegada (`seq`). Um consumidor de pull lê os eventos na ordem de `seq`.

A entrega push não mantém essa ordem. Os workers entregam em paralelo, e uma nova tentativa envia um evento que falhou depois dos eventos que vieram após ele.

O hub atribui e deduplica pelos headers do CloudEvents, não pela chave do registro Kafka. Um produtor que espalha (salga) um tenant quente por várias partições mantém a atribuição correta, mas o `seq` passa a refletir a ordem em que os eventos *chegaram* ao hub, não a ordem em que foram *produzidos*.

## Próximos passos

***

> [card] [Gerenciar subscriptions](https://docs.lerian.studio/pt/platform/streaming-hub/managing-subscriptions.md)
>
> O modelo de subscription, os fluxos de onboarding e a rotação de segredos.

> [card] [Consumir eventos](https://docs.lerian.studio/pt/platform/streaming-hub/consuming-events.md)
>
> Verifique assinaturas, deduplique e puxe eventos.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.