Como o curl 8.20.0 Resolveu Problemas de DNS em Threads: O Segredo do Resource Pooling
O Problema do DNS com Threads que Ninguém Menciona
Já parou para pensar no caos que rola nos bastidores quando o curl lida com dezenas de consultas DNS ao mesmo tempo? É o tipo de coisa que pode te deixar impressionado ou preocupado.
Antes, o resolvedor threadado do curl funcionava assim: a cada conexão paralela, criava uma thread nova e abria um socketpair (ou eventfd no Linux) para sincronizar os resultados. Ineficiente? Com certeza.
Para poucas transferências, isso passa batido. Mas em apps empresariais com milhares de conexões simultâneas? Aí o negócio complica. Cada thread gasta memória, CPU e recursos do SO. Cada socketpair aumenta o overhead de file descriptors. Com centenas de easy handles, o consumo explode de forma linear.
Pior ainda: se uma resolução DNS travasse, o cleanup inteiro parava. Tentar remover um easy handle com a thread presa? Deadlock na certa.
A Gambiarra Antiga (e Seus Problemas)
A equipe do curl tinha um paliativo: CURLOPT_QUICK_EXIT. Ative e as threads se desprendem em vez de esperar. Ótimo para apps que iam encerrar. Mas se o seu roda por horas? Threads soltas se acumulavam na memória, virando zumbis famintos por recursos até o fim do processo.
Pura gambiarra.
Pool de Threads: A Revolução do curl 8.20.0
A versão mais recente do curl joga fora o modelo antigo e traz pool de threads no nível do multi handle.
A nova estrutura é simples e esperta:
Um Pool Único para Muitas Conexões
Em vez de uma thread por easy handle, agora é um pool gerenciado por multi handle. Ele:
- Cria threads só quando precisa (sem desperdiçar)
- Mata threads ociosas após inatividade
- Enfileira pedidos de resolução DNS
- Notifica resultados de forma compartilhada
- Entrega respostas ao easy handle certo
O pulo do gato? Só um socketpair por multi handle, independente do número de conexões. Para apps com centenas ou milhares de transfers, isso corta o overhead de file descriptors pela raiz.
Você no Controle
Com CURLMOPT_RESOLVE_THREADS_MAX, defina o limite de threads do resolvedor. Padrão é 20, mas eles vão ajustar com feedback real.
Agora, adeus consumo descontrolado. Quer só 5 threads para poupar CPU? Configura. Precisa de 50 para throughput máximo? Fácil.
Tem também CURLMOPT_QUICK_EXIT no nível multi, para desligar o pool rápido no fim do processo. Sem threads por handle, remover easy handles é seguro — sem risco de joins travados.
Resoluções DNS que chegam atrasadas após remoção? Jogadas fora. Limpo e previsível.
Ganho de Performance (na Maioria dos Casos)
Além de economizar recursos, o pool traz um boost sutil: resoluções rolam em threads já ativas. Sem custo de startup, alocações repetidas ou syscalls extras.
Vai notar diferença brutal? Depende do seu app e máquina. Mas é sempre melhor — menos trocas de contexto, latência mais estável.
A Verdade Nua: Código Novo, Bugs Novos
Mudança grande assim traz mais código e partes móveis. Lugares perfeitos para bugs raros.
Os devs do curl confiam no trabalho, mas refators assim sempre revelam surpresas. Teste bem na sua setup antes de rodar em prod.
O Que Muda para Você
Apps de alto throughput com milhares de conexões paralelas (scrapers, pipelines de dados, downloaders distribuídos): curl 8.20.0+ corta memória, otimiza CPU e estabiliza recursos.
Sistemas embarcados ou IoT, onde cada byte conta: menos threads e file descriptors fazem diferença real.
Uso modesto? Melhoria invisível — resoluções mais rápidas, menos syscalls. Seu infra agradece.
Visão Geral
O que impressiona no projeto DNS 2026 do curl (onde esse pool é peça chave) é a engenharia madura: problema identificado, solução limpa, compatibilidade mantida e opções novas. Nada quebrado, tudo melhorado.
É assim que mantenedores open-source levam performance e recursos a sério.
Já testou o curl 8.20.0? Migrou sua infra? Comenta aí suas experiências — a equipe do curl usa feedback real para refinar essas mudanças.