O que rodar um bot em mais de 2.000 servidores do Discord nos ensinou
Quatro coisas que funcionam de outro jeito em grande escala do que você imagina enquanto escreve o código.

Um bot do Discord em três servidores e o mesmo bot em mais de dois mil não são o mesmo programa em tamanho maior. Algumas suposições que são totalmente inofensivas em pequena escala se tornam, a partir de certo tamanho, justamente os bugs mais difíceis de encontrar.
Aqui estão quatro que nos custaram falhas reais.
1. Falhas não se espalham por igual, elas se escondem
O AlphaCloud roda dividido em vários processos, chamados shards. O Discord decide qual servidor vai para qual shard, e cada shard só conhece os próprios servidores.
Isso produz um tipo de falha que, de fora, parece acaso: as mensagens de boas-vindas funcionam em alguns servidores e em outros não. Nenhum erro no log, nenhum alerta, nada. A causa era uma única chamada de rede sem timeout. Se o outro lado aceita a conexão e depois fica em silêncio, o código espera pelo resto da vida do processo. Tudo o que vem depois nunca acontece e, como nenhum erro é lançado, nada reporta um erro.
A lição não tem nada de espetacular e vale para tudo: toda chamada de saída precisa de um limite máximo. Uma chamada que espera para sempre é pior do que uma que falha, porque falhar pelo menos é visível.
2. Reiniciar não é correção, é prazo
Enquanto não sabíamos a causa, reiniciar o shard afetado sempre ajudava. Esse é exatamente o problema das reinicializações: elas funcionam, e isso tira a pressão de encontrar a causa.
Hoje tratamos "reiniciar ajuda?" como diagnóstico, não como remédio. Se ajuda, o estado quebrado vive na memória, e existe um lugar no código que o monta e nunca o desmonta.
O inverso também vale: tudo o que precisa sobreviver a uma reinicialização pertence ao banco de dados. Se uma operação de várias etapas está rodando, digamos uma mudança de cargo em milhares de membros, e o processo morre no meio, a operação não pode simplesmente sumir. Ela precisa ser detectada e continuada na próxima inicialização.
3. Os limites do Discord valem por bot, não por processo
O Discord limita quantas requisições por segundo um bot pode fazer. A suposição óbvia: mais processos, mais vazão. Errado. O limite é do bot, não do processo. Três shards, cada um com o orçamento completo, somam três vezes a cota, e aí o Discord estrangula os três.
Por isso, cada um dos nossos processos calcula quantos existem no total e pega só a sua parte. Parece óbvio, mas não era, e o bug ficou invisível por muito tempo porque cada processo, isoladamente, parecia se comportar perfeitamente.
Uma armadilha relacionada: tarefas recorrentes rodam em intervalos fixos, digamos a cada cinco minutos. Se todos os shards começam ao mesmo tempo, disparam suas tarefas no mesmo instante para sempre. Desde então, cada processo recebe um deslocamento aleatório ao iniciar.
4. O que as pessoas realmente configuram não é o que você espera
A parte técnica é uma metade. A outra: para a maioria dos servidores, o padrão é a configuração. Um módulo com padrões errados está mal configurado na grande maioria dos servidores, por melhor que seja a página de configurações.
Duas coisas decorrem disso para nós. Primeiro, cada padrão exige mais reflexão do que a própria configuração. Segundo, a pergunta melhor para um módulo novo não é "o que dá para configurar aqui", e sim "o que esse módulo faz quando ninguém configura nada, e isso está certo para um servidor normal".
Esse também é o motivo de uma decisão que, à primeira vista, parece o contrário: desde a v1.8.0, quase toda mensagem que o bot envia pode ser criada livremente. Mas blocos obrigatórios, como o motivo numa DM de advertência ou o menu de categorias num painel de ticket, podem ser movidos e não excluídos. Liberdade de design, sim, mas não a ponto de um servidor construir sem querer algo que parece funcionar e não funciona.
O fio condutor
Três dos quatro são a mesma ideia com roupas diferentes: nesse tamanho, uma falha silenciosa sai mais cara do que uma barulhenta. Um crash é reportado e corrigido. Um recurso que simplesmente para de fazer qualquer coisa pode continuar assim por meses, e você fica sabendo por um relato de bug de alguém que se deu ao trabalho de escrever.
Por isso, a primeira pergunta que fazemos hoje sobre código novo não é "isso funciona?", e sim "como isso fica quando não funciona, e nós perceberíamos?".
Mais artigos
De olho em 4.000 servidores do Discord: Grafana, PostHog e o que eles nos mostraram
Um loop que causava em silêncio metade do nosso tráfego, três milhões de requisições inúteis por dia e um ataque que acabou depois de um minuto. O que o nosso monitoramento vê e o que ele deliberadamente não vê.
BastidoresQuando o nosso provedor de IA desativou o modelo
Uma troca de modelo, respostas vazias sem erro e uma conta que de repente ficou várias vezes maior. O que quebrou e por que a causa era tão difícil de ver.
BastidoresA lei dentro do nosso código
Um botão de cancelamento que precisa funcionar sem login. Um formulário que nunca pode rejeitar você. Por que deveres legais são arquitetura para nós, e não texto padrão.