(Este é um texto do blog que eu mantenho. O corpo foi escrito com a ajuda de Shiro, a assistente de IA que trabalha comigo; se houver alguma interpretação equivocada, agradeço se me avisarem.)
Este é o registro de como o pequeno servidor do fediverso sukhi-fedi — uma rede social federada em que servidores se conectam entre si, como no Mastodon — removeu o fedify (uma biblioteca que rodava como worker Bun), responsável por montar JSON-LD (o trabalho de colocar mensagens em um formato que os servidores conseguem entender entre si) e por assinaturas HTTP (o procedimento de assinatura que verifica se a mensagem é autêntica), e reimplementou tudo diretamente em Elixir. Não é uma crítica maldosa: metade do texto é sobre “as qualidades do fedify que só percebi depois de partir”.
-
Para começar, eu não usava os recursos de framework do fedify (
createFederation, listener de inbox, dispatcher etc. — ferramentas de alto nível que cuidam de toda a funcionalidade de federação automaticamente), apenas emprestava as peças da camada mais baixa:- classes de vocabulário
toJsonLd/fromJsonLd(conversores que transformam formatos de mensagem de um lado para o outro)signRequest/verifyRequest, que conhecem os dois métodos de assinatura,draft-cavagee RFC 9421- assinaturas LD, document loader
- entrada e saída de chaves/JWK (formato padrão que contém chaves públicas)
-
Os motivos para sair foram três:
- No momento em que decidi não usar o framework, tudo que o fedify me dava “de graça” — responder
Accepta umFollow, idempotência (mecanismo para que, mesmo que a mesma requisição chegue várias vezes, o resultado seja refletido apenas uma vez), authorized fetch, instance actor — já precisava ser tratado diretamente por mim. O que restava eram só componentes básicos, então o volume a migrar já estava delimitado - O objetivo era rodar em um servidor pequeno, com 512–768 MB de memória, mas em um teste de durabilidade o Elixir concluiu de forma estável usando 130 MB, enquanto apenas o worker Bun sofreu OOM (morreu por falta de memória) em 120 MB. A única parte do sistema que rodava em outra linguagem era a mais pesada e a mais frágil
- A própria fronteira entre linguagem e processo gerava problemas. Preservar os dados originais necessários para verificar assinaturas, restaurar endereços que o túnel havia alterado, empacotar chaves do banco de dados como JWK para movê-las a outro processo etc. — não era culpa do fedify, mas era um encanamento que continuava crescendo
- No momento em que decidi não usar o framework, tudo que o fedify me dava “de graça” — responder
-
A substituição terminou em 12 arquivos e cerca de 2.100 linhas. Mantive a estrutura da fila de mensagens como estava, fiz o novo componente participar do mesmo grupo, e a transição foi simplesmente “parar o contêiner Bun”
-
Quem forneceu a rede de segurança foi o próprio fedify. Assinaturas Ed25519 e a normalização URDNA2015 (uma regra para organizar documentos sempre na mesma ordem) funcionam de modo que a mesma entrada sempre produz o mesmo resultado; assim, foi possível gerar previamente “dados corretos” com o código real do fedify e verificar que o resultado migrado para Elixir não diferia nem por um caractere
-
O worker Bun foi aposentado, mas não removido. Até hoje ele permanece no ambiente de desenvolvimento com a função de gerar os dados corretos
-
A equipe do fedify está criando o DrFed (https://drfed.org/), uma ferramenta de depuração de ActivityPub. Ela deverá incluir diagnósticos que apontam em qual etapa da federação (DNS/TLS/HTTP/assinatura/JSON-LD) algo quebrou, além de um depurador que permite acompanhar passo a passo os dois métodos de assinatura (com apoio do NLnet NGI0, open source sob AGPL-3.0, atualmente em desenvolvimento)
-
Em resumo: também é uma forma de dizer que, se você pretende usar um framework completo em TypeScript/JavaScript, o fedify continua sendo a melhor escolha. O recurso de ActivityPub do Ghost, o hackers.pub e o Hollo rodam todos sobre ele
Ainda não há comentários.