SonaCORE

Garantias

O que se sustenta, e o que não.

Esta página declara as garantias sobre as quais você pode construir e nomeia os estados surpreendentes que você ainda pode observar. As duas metades importam: um cliente escrito contra a primeira metade sozinha vai, em algum momento, ler um saldo defasado e concluir que dinheiro desapareceu.

O princípio central

Uma obrigação é tornada durável no nosso banco de dados antes de a transação ser submetida ao ledger. O conjunto de saídas não gastas do ledger é a autoridade de liquidação; o banco de dados é o registro de intenção e a origem do modelo de leitura.

Duas consequências decorrem disso, e todo o resto desta página vem delas:

O que um observador vê, fase por fase

FaseEstadoQuem lê vê
RegistradaOPENA obrigação existe e é durável. Nada está no ledger. Ela não está em nenhum saldo.
SubmetidaPENDINGA transação está com o processador. Legível por id. Ainda não está em um saldo.
ConfirmadaPENDING → FINALEstá no ledger. O modelo de leitura se atualiza logo depois, e nesse momento ela entra nos saldos.
ResolvidaFINALO ciclo de vida fechou e o desfecho da resolução está definido. Este é o único ponto em que 'liquidado' é uma afirmação verdadeira.

Read-your-writes vale para um tipo de leitura

Ler uma obrigação pelo id é read-your-writes: é uma busca por chave e vai sempre refletir uma escrita que você acabou de fazer. Ler um saldo não é: é uma consulta a índice, e o índice é atualizado de forma assíncrona.

Consulte a obrigação, nunca o saldo
Para saber se algo funcionou, consulte a obrigação pelo id. Nunca deduza liquidação de uma variação de saldo, e nunca trate um saldo que não mudou como falha. Essa é a maneira mais comum de construir um cliente que reporta perdas fantasma.
a consulta correta
GET /v1/obligations/{obligation_id}   # por chave, read-your-writes
GET /v1/accounts/{account_id}/balance # consulta a índice, consistência eventual

FINAL é um estado de ciclo de vida, não uma afirmação de liquidação

FINAL significa que a obrigação não vai mudar de novo. Não significa que o valor se moveu. Uma obrigação pode estar FINAL com o desfecho da resolução ainda em branco, e pode estar FINAL tendo falhado.

o único teste correto de liquidação
liquidado = obligation.state == "FINAL"
        and obligation.resolution_outcome == "SETTLED"

Se você levar uma linha de código destes documentos, leve essa. Um filtro escrito como state == "FINAL" vai contar falhas como sucessos.

A defasagem é limitada na prática, e não por contrato

Uma transação confirmada chega a uma leitura de saldo depois de dois saltos assíncronos: o indexador a projeta, e o índice que ele escreve se propaga. Localmente os dois são abaixo de um segundo. Nenhum dos dois é um limite contratual, e não publicamos número para eles, porque nenhuma medição que fizemos mede aquilo que um número desses seria citado para prometer.

Projete considerando isso, e não contornando: consulte por id, use a linha do tempo da obrigação para histórico, e trate um saldo como uma visão que é correta, não instantânea.

Anomalias que você pode observar

Nomeá-las é deliberado. Um modelo de consistência sem lista de anomalias é ou mais forte que qualquer sistema real, ou menos honesto que um.

AnomaliaSintomaO que você faz
Mutações concorrentes em um grupodescartada em silêncioDuas mutações seguidas na configuração do mesmo grupo podem devolver 201 as duas, e a que perde o gasto duplo subjacente é descartada da projeção. Serialize: consulte a composição do grupo entre as chamadas em vez de disparar as duas juntas. Depósitos em um grupo apenas leem a configuração, então não competem.
Defasagem de saldolançamento ausenteUma transação recém-confirmada pode não estar na próxima leitura de saldo. Leia a obrigação pelo id para ter o estado definitivo.
Um 500 ao criar um gruporepetirA projeção é escrita como um grupo atômico, então uma falha persistente de banco aparece como 500 em vez de sucesso parcial. O grupo em si já está no ledger e a projeção é reconstruível a partir dele, então um 500 aqui quer dizer repetir, não investigar.
Uma escrita repetida depois de uma quedaseguroSe cairmos entre aplicar uma operação e registrar a chave de idempotência dela, a sua repetição reexecuta. A segunda tentativa tenta gastar as mesmas saídas e o ledger rejeita a perdedora, então o resultado é um efeito, não dois.

Existem outras anomalias cuja mitigação é nossa e não sua: uma obrigação que fica registrada e nunca é submetida depois de uma queda, e um crédito externo cujo processamento foi interrompido. As duas são detectadas por uma varredura de conciliação e resolvidas com ferramental de operação. Mencionamos porque uma lista que contivesse só os seus problemas seria uma lista incompleta, não porque você precisa programar para elas.

O que não afirmamos