Resumo
- No ONC RPC, toda CALL começa com um XID de 32 bits, copiado na REPLY. O solicitante associa a resposta à espera correta e o servidor pode comparar igualdade para suspeitar de retransmissão, mas o campo não é sequência nem certificado de execução única.
- A experiência do NFS revelou a memória ausente. O cache volátil de duplicatas do NFSv3 reduzia reexecuções dentro de uma janela; o NFSv4.1 usou sessões, slots limitados, sequence IDs por slot e respostas retidas para tornar o custo da semântica mais forte explícito.
O mesmo silêncio comportava resultados opostos
Um cliente pede a remoção de um nome. O servidor pode concluir a remoção e perder apenas a resposta, ou a chamada pode desaparecer antes de chegar. Em ambos os casos, o cliente vê o cronômetro vencer sem resultado.
Enviar outra cópia é racional, mas não é neutro. Se a primeira já produziu efeito, a segunda pode repetir uma ação não idempotente ou devolver um erro diferente do resultado original. Se a primeira nunca chegou, rejeitar a cópia como antiga impediria o único pedido real.
O RFC 1050, de abril de 1988, já separava o protocolo de mensagens RPC da confiabilidade. O RFC 1057, publicado dois meses depois, preservou a conclusão incômoda: com UDP, retransmitir e continuar sem resposta não permite inferir quantas vezes o procedimento rodou; receber uma resposta demonstra apenas pelo menos uma execução.
O timeout mede a observação do cliente, não o estado do servidor. Não existe valor de espera que, sozinho, transforme ausência de mensagem em prova de ausência de efeito.
XID era endereço de retorno lógico, não livro-caixa
O formato RPC version 2 põe um inteiro sem sinal de 32 bits no início de cada mensagem. A resposta retorna o XID da chamada que a originou. Assim, várias operações podem ficar pendentes e o cliente sabe a qual delas entregar cada resultado.
O RFC 5531 restringe a leitura feita pelo serviço. Ele pode usar igualdade entre XIDs para detectar uma possível retransmissão, mas não pode interpretar o campo como sequence number. A distância numérica entre dois XIDs não representa tempo, ordem ou causalidade.
O protocolo-base também não obriga a memória. A aplicação cliente pode reutilizar o XID anterior ao retransmitir. O servidor pode guardar esse valor depois de executar e evitar executar novamente uma chamada com o mesmo valor. Algum comportamento execute-at-most-once surge se as duas escolhas combinam e se o registro continua vivo.
Mudar o XID no retry perde o elo. Reiniciar ou expulsar a entrada perde o elo. Reutilizar o número mais tarde pode criar um falso elo quando o escopo não inclui solicitante, programa, versão, procedimento, argumentos relevantes e época do servidor. O inteiro é comparável; o sistema decide o significado da comparação.
Uma conexão confiável não arquivava o processo remoto
O RFC 1831 manteve essa arquitetura, e o RFC 5531 a consolidou no Standards Track. Os textos dizem que uma resposta recebida por transporte confiável permite inferir exatamente uma execução no modelo daquele intercâmbio. A ausência da resposta, porém, continua sem provar que nada ocorreu; timeouts e reconexão ainda são necessários para falhas do servidor.
TCP conserva ordem e entrega dentro de uma conexão. Ele não preserva o histórico da aplicação quando o processo cai depois de alterar estado. A nova conexão aberta pelo cliente não carrega um veredito sobre a chamada da conexão anterior.
XID também não é autenticação. O RPC define credentials e verifiers em campos separados. Um XID coincidente associa mensagens segundo o estado local do requester; não identifica sozinho o principal, não assina argumentos e não certifica commit durável.
A simplicidade stateless do NFS tinha uma dívida
O NFS inicial quis servidores tão stateless quanto possível. Segundo o RFC 1094, o cliente poderia continuar tentando depois de uma queda ou interrupção, sem reconstruir estado de protocolo no servidor.
Para suportar isso, as operações deveriam ser idempotentes sempre que viável. Ler novamente ou escrever os mesmos dados no mesmo trecho podia ter efeito equivalente. Mas REMOVE, RENAME, LINK, MKDIR e outros procedimentos eram assinalados como possivelmente não idempotentes. Depois do primeiro sucesso, o mundo já não oferece as mesmas precondições para a segunda cópia.
O RFC 1813 tornou o risco concreto no NFSv3. Reexecutar uma operação não idempotente podia ser destrutivo; truncar outra vez podia apagar writes posteriores. Mesmo sobre transporte orientado a conexão, uma quebra seguida de restabelecimento exigia tratar uma chamada retransmitida cujo primeiro resultado era desconhecido.
Stateless não significava ausência de estado nos arquivos. Significava que a conversa não guardava tudo. A responsabilidade reaparecia na definição de cada operação e em algum mecanismo que reconhecesse duplicatas.
O cache respondia por um intervalo, não para sempre
Muitos servidores NFSv3 mantinham um duplicate request cache. Ao terminar uma chamada, guardavam o status original. Se a mesma solicitação voltasse enquanto a entrada existia, devolviam o resultado salvo em vez de aplicar o procedimento de novo.
Esse cache participava da correção. A decisão permanecia junto de quem executou a ação. Contudo, o próprio RFC 1813 descreveu sua fragilidade. A implementação típica usava RAM, portanto uma queda apagava a memória. O tamanho finito permitia eviction; uma partição longa podia remover a entrada antes de o cliente receber a resposta. O retry posterior parecia novo.
Chamar XID de chave durável de idempotência esconderia o principal. A promessa depende da chave composta, do tempo de retenção, da política de substituição, da persistência, da identidade depois do failover e da associação com o resultado.
O EXCLUSIVE CREATE do NFSv3 mostrou uma saída localizada. Um verifier relacionado ao objeto criado podia reconhecer a repetição quando o cache normal não bastava. A prova mais forte ficava perto do estado protegido, sem transformar todos os XIDs em autoridade universal.
Slots deram um limite operacional à memória
O NFSv4.1 não tentou guardar para sempre todo XID visto. O RFC 5661 introduziu sessions, e o atual RFC 8881 define uma tabela limitada de slots. Cada slot conserva um sequence ID e a resposta referente ao pedido corrente.
O requester escolhe um slot livre. Um pedido novo avança a sequência daquele slot; um retry repete a sequência atual. O replier consegue classificar localmente o próximo pedido, a cópia do pedido corrente e um valor fora de ordem. Quando a execução original já terminou, a cópia recebe a resposta armazenada.
O limite de slots restringe tanto a concorrência quanto a obrigação do cache. O servidor sabe o máximo de respostas que precisa custodiar para aquele canal. A próxima sequência também demonstra que o cliente avançou, permitindo substituir o resultado anterior do slot.
O RFC 8881 contrasta essa estrutura com XIDs opacos. Chamadas RPC podem concluir em qualquer ordem e não há, no campo, um limite natural de pendências. Guardar respostas para todo o espaço de 32 bits seria impraticável. O slot converte uma história aberta em um conjunto negociado de responsabilidades atuais.
Exactly once continuava dependendo de persistência
Uma tabela limitada ainda pode desaparecer. Para sustentar EOS através de restart, o estado de recuperação e o reply cache relevante precisam sobreviver. Uma implementação volátil melhora retries normais, mas não pode atestar uma resposta que perdeu.
O NFSv4.1 não aboliu o XID. A camada RPC ainda o usa para ligar CALL e REPLY, inclusive em operações fora do caminho SEQUENCE habitual. Session ID, slot ID e sequence ID adicionam o contexto necessário à execução; não substituem todas as funções por um número central.
A evolução, portanto, acrescentou deveres. XID localiza. O cache preserva temporariamente. O slot limita o volume e define quando liberar. A persistência delimita as falhas que a alegação de uma única execução consegue atravessar.
O que igualdade não autoriza concluir
Dois XIDs iguais não demonstram argumentos iguais, mesmo principal, mesma instância ou mesma boot epoch. Cache miss não comprova novidade; cache hit não comprova que o efeito chegou ao armazenamento estável. Até uma operação idempotente pode sofrer com a ordem: o RFC 8881 mostra um WRITE antigo, ainda pendente, executando depois e sobrescrevendo um WRITE mais novo.
O campo oferece uma pergunta local: estes valores são iguais? A resposta sobre uma única execução exige que o executor conserve a ligação entre número, trabalho, resultado, escopo e recuperação durante toda a incerteza do cliente.
Fontes e limites da evidência
A linhagem RPC está nos RFCs 1050, 1057, 1831 e 5531. A opção stateless do NFS vem do RFC 1094; o duplicate request cache e suas janelas, do RFC 1813. As sessions NFSv4.1 foram introduzidas no RFC 5661 e hoje estão no RFC 8881. Esses documentos registram regras e modelos de falha, não a capacidade atual de caches, sua persistência, adoção ou conformidade em todos os produtos.
Briefing para membros
Contexto aprofundado do perfil
Faça login com o nível de assinatura correto para desbloquear o briefing completo e as notas das fontes.
Apenas para Strategic Circle
Strategic Circle
Aberto a todos os leitores. Desbloqueie Briefings de perfil após se inscrever e fazer login.
Junte-se ao Strategic CircleSomente para Leadership Alliance
Leadership Alliance
Para proprietários e gestores qualificados de ativos de PI; faça login para desbloquear os briefings da Leadership Alliance.
Junte-se ao Leadership Alliance
