Pular para o conteúdo
ColliePWA

10/Documentation

O protocolo de rede durable (experimental)

O que trafega entre o Collie e um durable agent, para desenvolvedores: as rotas, hello e a época, a vida útil de uma solicitação e os IDs de requisição, os transportes por socket e token, os limites e a regra de versão, com um link para WIRE.md para ver as regras exatas

Experimental. O protocolo pode mudar ou o recurso pode ser removido em uma versão minor posterior. Versões e a saudação de identificação explica como uma alteração chega até você.

O protocolo durável é a forma como o Collie se comunica com um agente durável. Esta página explica seu funcionamento para quem cria um agente durável sem o SDK ou deseja saber o que o SDK faz. As regras exatas estão em WIRE.md e, onde esta página e esse arquivo divergirem, WIRE.md está correto. O SDK durável implementa tudo isso para você.

O que trafega

O Collie disca e o agente durável escuta, e cada troca é uma requisição HTTP com corpo JSON.

O agente durável escuta em um socket Unix privado, ou atrás de TLS em uma URL (Transportes). O Collie faz polling nele: não há push, nem WebSocket e nem stream. Cada caminho começa com /session/v1, que é um nome fixo, não a versão. Todas as chamadas, exceto a primeira hello, carregam a versão no cabeçalho X-Collie-Session. O corpo da requisição é um objeto JSON de no máximo 64 KiB, e um corpo POST vazio é interpretado como {}.

método e caminhoo que fazlimite de resposta
GET /helloNome, intervalo de versões, época, prontidão e recursos do agente durável16 KiB
GET /snapshotO layout: workspaces, abas, painéis com seus estados, turnos e solicitações abertas, e inicializadores. Carrega uma ETag e responde 304 quando nada foi alterado4 MiB
GET /pane/:id/events?after=N&epoch=EEventos do painel após um cursor8 MiB
POST /pane/:id/answerUma resposta para uma pergunta16 KiB
POST /pane/:id/sendTexto para o painel, para direcionar o turno atual ou aguardar o próximo16 KiB
POST /pane/:id/abortInterromper o turno atual16 KiB
POST /pane/:id/actionUm clique em um dos botões da faixa do painel16 KiB
POST /renameUm novo título para um workspace ou uma aba16 KiB
POST /closeFechar um painel, uma aba ou uma workspace16 KiB
POST /starter/:idExecutar um inicializador. A resposta nomeia o novo painel16 KiB
GET /conversations?after=C&limit=NConversas do agente durável, abertas e fechadas, as mais recentes primeiro1 MiB
GET /conversation/:id/items?after=C&limit=NItens de uma conversa, os mais antigos primeiro8 MiB
POST /reopenExibir uma conversa fechada novamente16 KiB

Todo erro é um corpo JSON com um code, como 409 stale ou 404 no-such-pane. Qualquer outro caminho responde 404 not-found. Uma resposta acima do seu limite não é lida, e um POST com resposta truncada tem resultado desconhecido (IDs de requisição).

Hello e época

hello informa quem é o agente durável, e a época informa com qual inicialização dele o Collie está se comunicando.

campo de helloo que ela contém
serviceExatamente collie-durable. Sem isso, o Collie interpreta o agente durável como outro servidor e não faz outras chamadas
protocolO intervalo de versões de comunicação que o agente durável suporta, { min, max }. Hoje { min: 1, max: 1 }
host.nameO nome do próprio agente durável, apenas texto para exibição, no máximo 64 bytes
epochNovo e aleatório a cada inicialização do agente durável, pelo menos 128 bits, nunca reutilizado
readyFalse enquanto o agente durável organiza seus painéis após uma inicialização
capsO que o agente durável pode fazer, cada um como booleano. Uma funcionalidade ausente é false

O Collie primeiro chama hello sem o cabeçalho de versão, escolhe a versão mais alta aceita por ambos os lados e a envia em todas as chamadas posteriores. Enquanto ready for false, todas as rotas exceto hello respondem 503 starting, e o celular mostra o agente durável como iniciando. Um agente durável define ready somente depois que todas as conversas forem exibidas novamente e todas as solicitações abertas forem feitas de novo, de modo que um reinício nunca mostre um layout pela metade.

O ETag do snapshot é "<epoch>-<rev>". rev aumenta a cada alteração visível para o leitor, portanto um 304 quase não consome recursos do agente durável. Uma nova época indica ao Collie que o agente durável reiniciou. O Collie continua exibindo os painéis que já tem até ler o novo snapshot. Em seguida, ele lê cada painel com o cursor antigo e obtém a visualização atual completa do painel em uma única resposta.

Uma leitura com falha após uma bem-sucedida mantém o último snapshot para aquela sondagem. Duas falhas seguidas mostram o agente durável como inacessível. Um caminho de socket que falhe na verificação de permissões fica inacessível imediatamente.

Perguntas e respostas

Uma pergunta é um card de dúvida, e fica aberta a partir do evento ask do agente durável até o seu ask-closed.

estadoquem defineo que o telefone exibe
AbertoO agente durável faz a pergunta. O painel exibe waiting enquanto houver perguntas abertasUm card em "Precisa da sua resposta", com o nome do agente durável e o tempo restante quando a pergunta tiver expiresAt
AlteradoO agente durável altera a pergunta no local, e seu revision aumentaO card é redesenhado. Um toque no formulário antigo recebe 409 stale, e o card diz "Esta pergunta mudou. Leia novamente e toque em uma resposta."
RespondidoO celular responde, e o agente durável encerra a pergunta com by: "phone"O card desaparece, e a ferramenta é executada ou negada conforme a opção indicar
Decidido no agente durávelO agente durável encerra a pergunta por conta própria, decidedBy: "program". Uma interrupção do turno é contabilizadaUma linha no Chat que começa com "Decidido no agente durável", com o título da pergunta
Tempo esgotadoO tempo ultrapassa expiresAt, decidedBy: "timeout"Uma linha no Chat que começa com "Tempo esgotado antes de uma resposta", com o título da pergunta

Um toque que chega após a decisão recebe 409 decided com o primeiro resultado, e nada é executado. O card então indica quem decidiu primeiro: "Decidido no agente durável.", "Tempo esgotado antes de uma resposta." ou, após outro toque, "Já respondido. Este card sumirá na próxima atualização.". Uma pergunta que o agente durável não conhece mais responde 200 too-late. O card diz então "Não processado. A pergunta pode reaparecer em instantes.", porque após um reinício o agente durável pode fazê-la novamente sob o mesmo id.

regrapor que
O id da solicitação é um hash do id do painel e do id da chamada de ferramentaA mesma chamada de ferramenta feita após um reinício tem o mesmo id, permitindo que uma resposta enviada durante o reinício seja entregue
Um card permission é gerado a partir do nome da ferramenta e de seus argumentos, nunca das palavras do modeloUm modelo que busca aprovação descreveria a chamada de forma favorável
Um agente durável protegido por TLS não deve oferecer allow-alwaysO token é o único controle de acesso, portanto uma única resposta de quem o possuir liberaria todas as chamadas seguintes
O celular não oferece allow-always em um card cujas palavras foram cortadas ou limpas, ou que não nomeia nenhuma ferramentaA pessoa não consegue ver o que a concessão cobre
expiresAt é ISO 8601 com fuso horárioApós esse prazo, o pedido é decidido por timeout, e um snapshot não o lista mais como aberto
O durable agent mantém o resultado de pelo menos seus últimos 500 pedidos decididos por painelUm toque atrasado recebe decided e o primeiro resultado, não um too-late simples

Um pedido é de um de quatro tipos: permission, choice, text ou form. Cada um tem seu próprio formato de resposta, listado com o Perguntas do SDK.

IDs de requisição

Cada ação do celular tem um request id, portanto é executada no máximo uma vez.

O celular gera um request id por intenção, e o Collie grava seu próprio recibo antes de repassar o id. O durable agent mantém pelo menos os últimos 500 ids de sua época. Uma repetição de um id finalizado recebe a primeira resposta novamente com replayed: true e não executa nada. O mesmo id com outro payload recebe 409 request-id-reused.

O Collie nunca repete um POST por conta própria. Um POST que expira, perde a conexão ou recebe um 5xx tem resultado desconhecido. Para uma resposta, o card diz então "Não há certeza de que a resposta chegou. Tentar novamente envia mais uma vez.", e Tentar novamente envia o mesmo request id, para que a memória do durable agent responda a repetição.

Uma nova tentativa que encontra o pedido fechado ou a vez alterada não consegue saber se a primeira tentativa teve efeito. O Collie então responde ao celular "talvez aplicado", o card diz "Pode já ter sido aplicado. Verifique o chat.", e a ação nunca é enviada uma terceira vez.

Transportes

Um durable agent usa um de dois transportes: um socket privado na máquina do Collie ou TLS com um token.

Os bytes são os mesmos em ambos: as rotas, os corpos, o cabeçalho de versão, o ETag e os códigos de erro. Apenas quem pode alcançar o durable agent difere.

pelo socketa regra
CaminhoAbsoluto, no máximo 103 bytes. Ambos os lados o leem de COLLIE_DURABLE_SOCKET
ModosO socket tem modo 0600, em uma pasta com modo 0700. O durable agent remove um arquivo de socket obsoleto antes de escutar
A verificação do caminhoAntes de cada conexão, o Collie verifica cada parte do caminho com lstat. Nenhuma parte é um link simbólico. A pasta do socket é sua com modo 0700. Nenhuma pasta acima dela tem permissão de escrita para grupo ou outros, exceto uma com sticky bit como /tmp. O socket é seu, sem permissão para grupo ou outros
Uma verificação com falhaO Collie não conecta e mostra o durable agent como inacessível com socket-not-private e a parte que falhou
TokenNenhuma. O socket privado é o controle de acesso
Quem pode agirQualquer processo do seu usuário. O durable agent pode recusar seus próprios descendentes com 403 caller-refused
Timeouts1000 ms para hello, snapshot e events. 3000 ms para answer, send, stop, action, rename ou close. 30000 ms para um starter
Com que frequência o Collie consultaA cada 1 s enquanto um celular monitora, caso contrário a cada 3 s. Um durable agent fora do ar é consultado uma vez por verificação
SistemasLinux e macOS. O Windows não tem transporte por socket
via TLSa regra
URLhttps://, ou http://127.0.0.1:<port> ou http://localhost:<port> para um teste local. No máximo 2048 bytes, sem nome de usuário ou senha, sem query, sem fragmento. O Collie adiciona /session/v1 a isso
TokenPelo menos 32 bytes, ASCII imprimível sem espaços. O Collie envia Authorization: Bearer <token> em cada requisição, hello incluído
A verificação do agente durávelO token primeiro, antes da versão, hello e ready, comparado em tempo constante. Um token ausente ou incorreto recebe um 401 { "code": "unauthorized" } simples e nada mais
RedirecionamentosO Collie não segue nenhum. Um 3xx é repassado como status, para que o token nunca chegue a outro host
ETagUm proxy que compacta uma resposta pode enfraquecer a tag para W/"<epoch>-<rev>". Ambos os lados a comparam com o W/ removido
Uma recusaUm 401 ou 403 mostra o agente durável como inacessível com token-refused
Timeouts5000 ms para cada leitura e gravação, pois um agente durável que dormiu pode acordar frio. 30000 ms para um starter
Com que frequência o Collie consultaA cada 2 s enquanto um telefone monitora, caso contrário a cada 10 s. Um agente durável inativo ou recusado é consultado no máximo uma vez a cada 10 s

Cada tempo limite é um prazo para toda a troca, da conexão até o último byte. Via TLS, cada sondagem é uma requisição que seu host pode cobrar, inclusive um 304.

Limites

O Collie corta ou recusa qualquer coisa além desses limites, portanto um agente durável que permaneça dentro deles não perde nada.

o quelimite
Workspaces por snapshot64
Abas por snapshot256
Painéis por snapshot256
Perguntas abertas por painel50, as mais antigas primeiro
Opções de um permission6
Opções de um choice e de um campo de escolha8
Campos de um form6
Starters por snapshot50
Botões da barra por painel4, um rótulo de 16 caracteres
Um id1 a 128 bytes, sem caractere de controle, sem espaço em branco, nenhum entre /, ? ou #
Um corpo de requisição64 KiB, caso contrário 413 too-large
Respostashello 16 KiB, snapshot 4 MiB, events 8 MiB, conversations 1 MiB, items 8 MiB, um POST 16 KiB
Eventos por resposta1000. Um leitor que ficou para trás recebe a visualização atual, no máximo os 2000 itens mais recentes
Texto de um item user, reply, thinking ou notice64 KiB
Texto de um item markdown ou code32 KiB
Texto que o telefone envia32 KiB
Um item linkApenas https://, no máximo 2048 caracteres
Uma página de histórico100 conversas, ou 1000 itens
Um cursor de histórico512 bytes de ASCII imprimível, sem espaço

Uma string acima do limite é truncada, e seus caracteres de controle e invisíveis são removidos. Uma lista acima do limite mantém suas primeiras entradas. Uma página de histórico acima do limite não é lida.

Versões e a saudação de identificação

Hoje existe uma versão de protocolo, 1, e o Collie fala 1..1.

Quando a versão 2 for lançada, o Collie aceitará a versão 1 por uma versão minor seguinte, e a minor posterior a essa deixará de aceitá-la. Um leitor ignora um campo, um tipo de evento, um tipo de item ou um código que não reconhece. Um campo adicionado dentro da versão 1, como expiresAt ou decidedBy, é opcional. Um novo campo obrigatório, um novo significado para um campo antigo ou um campo removido exige uma nova versão.

Um ask de um tipo que o telefone não conhece aparece como um que ele não pode responder a partir do telefone, sem botões.

Quando os dois intervalos não se encontram, o Collie não lê mais nada do durable agent. Uma vez por época do durable agent, ele envia mais um hello, desta vez com sua própria versão, para que o durable agent possa registrar o desencontro do seu lado. O durable agent responde 409 incompatible com um refusal que lista ambos os intervalos. Esse é o telling hello.

O Collie grava uma linha no seu log para cada intervalo que recusa, e collie doctor mostra ambos os intervalos. A tela inicial do durable agent no telefone exibe a mesma frase, por exemplo "The durable agent speaks wire v2, this Collie speaks v1. Update Collie, or the agent's SDK." Atualize o lado mais antigo.

Onde estão as regras exatas

WIRE.md é o contrato, com cada formato, código e regra.

As decisões por trás dele são registros no repositório:

registroo que ele decide
ADR 0099Um agente durável é um multiplexador sem tela
ADR 0100Uma solicitação viaja como dados e é respondida por id
ADR 0101Send e stop nomeiam o turno que o telefone viu
ADR 0102Starters são linhas na página New
ADR 0103Os dois transportes
ADR 0104Um agente durável é uma sessão, e a saída
ADR 0105O SDK é um pacote npm

Editar esta página no GitHub

The rest of the documentation