تكرار السؤال: …
الإجابة المختصرة
تحدث عندما تحتكر عمليات تشفير ثقيلة أو قراءات ملفات متزامنة خيوط libuv الأربعة الافتراضية مما يؤخر طلبات DNS وباقي مهام الـ I/O الأخرى.
الشرح
نظراً لأن وحدة crypto (مثل bcrypt أو pbkdf2) وعمليات نظام الملفات fs وحل أسماء النطاقات dns.lookup تتشارك نفس الـ threadpool الصغير، فإن تسجيل دخول 4 مستخدمين في نفس اللحظة قد يشغل كامل الخيوط ويمنع السيرفر من حل أي عنوان DNS حتى ينتهي التشفير. رفع الحجم إلى 16 أو 64 خيطاً يحل هذا الاختناق.
مثال بالكود
import crypto from "node:crypto";
import { promisify } from "node:util";
const pbkdf2 = promisify(crypto.pbkdf2); // runs in libuv's thread pool (4 threads by default)
console.time("8 hashes");
await Promise.all(Array.from({ length: 8 }, () => pbkdf2("password", "salt", 200_000, 64, "sha512")));
console.timeEnd("8 hashes");
// Run again with a bigger pool — must be set BEFORE the pool is first used:
// UV_THREADPOOL_SIZE=8 node app.js
// fs, crypto, zlib and dns.lookup share this pool, so heavy hashing can delay unrelated file/DNS work.أخطاء شائعة
- توقع حل مشكلة تجويع الـ threadpool لمهام الـ CPU الصرفة؛ الـ threadpool مخصص فقط لمهام libuv وليس لأي كود JavaScript عادي.