Jak curl 8.20.0 ogarnął wątki w rozwiązywaniu DNS: pooling zasobów pod lupą
Problem z wątkami DNS w curl, o którym mało kto mówi
Wyobraź sobie, że curl musi obsłużyć kilkadziesiąt równoczesnych zapytań DNS. Co dzieje się w tle? To może cię zaskoczyć – i niekoniecznie pozytywnie.
Do niedawna mechanizm wielowątkowy w curl działał prosto: na każde połączenie parallelne biblioteka tworzyła nowy wątek. Do tego otwierała socketpair (albo eventfd na Linuksie), żeby synchronizować wyniki. Brzmi marnotrawnie? Bo tak było.
Przy kilku transferach nie zauważysz problemu. Ale w aplikacjach enterprise z tysiącami połączeń? Katastrofa. Każdy wątek zżera pamięć, CPU i zasoby systemu. Socketpair to dodatkowe obciążenie deskryptorów plików. Pomnóż przez tysiące easy handles – i masz liniowy wzrost zużycia zasobów.
Gorzej: gdy DNS się zawiesił, blokował cały cleanup. Usuwanie easy handle z utkniętym wątkiem? Cześć, deadlock w aplikacji.
Stara łata, która nie rozwiązywała problemu
Zespół curl miał obejście: CURLOPT_QUICK_EXIT. Ustawiasz to, wątki się detachują zamiast joinować – idealne na koniec aplikacji. Ale jeśli program działa dalej? Wątki wiszą w pamięci jak duchy, kumulując zasoby do restartu.
To był typowy hack.
Basen wątków: rewolucja w curl 8.20.0
Nowa wersja curl wyrzuca stary model do kosza. Wchodzi pula wątków na poziomie multi handle.
Nowy system wygląda tak:
Jedna pula dla wielu połączeń
Zamiast wątku na easy handle masz pulę zarządzaną na multi handle. Ona:
- Uruchamia wątki tylko na żądanie (bez marnowania na starcie)
- Wyłącza bezczynne po czasie
- Stawia zapytania DNS w kolejce
- Wysyła wyniki przez wspólny mechanizm powiadomień
- Przydziela gotowe odpowiedzi do właściwych easy handles
Kluczowe: jeden socketpair na multi handle, niezależnie od liczby połączeń. Dla setek czy tysięcy transferów to ogromna oszczędność deskryptorów plików.
Kontrola w twoich rękach
Nowa opcja CURLMOPT_RESOLVE_THREADS_MAX pozwala ustawić limit wątków resolvera. Domyślnie 20 – zespół curl dopracuje to na podstawie testów.
Nie jesteś już bezradny wobec zużycia zasobów. Chcesz tylko 5 wątków, by oszczędzić CPU na logikę appki? Ustaw 5. Potrzebujesz 50 dla max przepustowości? Proste.
Jest też CURLMOPT_QUICK_EXIT na poziomie multi. Działa jak stary, ale teraz bezpieczniej – easy handles nie blokują się na joinach. Późne DNS po usunięciu handle'a? Po prostu wyrzucone. Czysto i przewidywalnie.
Zyski w wydajności (zazwyczaj)
Oprócz oszczędności zasobów, pula daje realny boost: DNS-y lecą w już działających wątkach. Bez overheadu startu, alokacji pamięci czy powtórnych syscalli.
Czy zauważysz skok? Zależy od twojej appki i hardware'u. Ale zawsze lepiej niż dawniej – mniej operacji, mniej przełączania kontekstu, stabilniejsze opóźnienia.
Ostrzeżenie: nowa architektura, nowe błędy
To duża zmiana w kodzie. Więcej części ruchomych, więcej miejsc na edge case'y.
Twórcy curl wierzą, że nic nie zepsuli, ale refaktory zawsze mają pułapki. Testuj nowe wydanie w swoim środowisku.
Co to znaczy dla ciebie
Budujesz appki high-throughput z tysiącami połączeń (scrapery webowe, pipeline'y danych, downloader'y rozproszone)? curl 8.20.0+ to spory upgrade. Mniej pamięci, lepiej CPU, stabilne zasoby.
Robisz embedded czy IoT? Oszczędność na wątkach i deskryptorach może być kluczowa – każdy bajt i cykl się liczy.
Używasz curl na małą skalę? Poprawki działają w tle. DNS-y szybsze, mniej syscalli. Nie widać, ale infrastruktura dziękuje.
Szerszy kontekst
Inicjatywa DNS 2026 curl (gdzie pula wątków to kluczowy element) pokazuje dojrzałą inżynierię: problem zidentyfikowany, rozwiązanie czyste, kompatybilność zachowana, nowe opcje. Nic nie zepsute, wszystko ulepszone.
Tak wygląda open source, gdy maintainerzy traktują perf i zasoby serio.
Testowałeś już curl 8.20.0? Przerabiasz infrastrukturę? Daj znać w komentarzu – zespół curl słucha feedbacku z realnego świata.