1'use strict'; 2 3// Test to validate massive dns lookups do not block filesytem I/O 4// (or any fast I/O). Prior to https://github.com/libuv/libuv/pull/1845 5// few back-to-back dns lookups were sufficient to engage libuv 6// threadpool workers in a blocking manner, throttling other work items 7// that need pool resources. Start slow and fast I/Os together, make sure 8// fast I/O can complete in at least in 1/100th of time for slow I/O. 9// TEST TIME TO COMPLETION: ~5 seconds. 10 11const common = require('../common'); 12const dns = require('dns'); 13const fs = require('fs'); 14const assert = require('assert'); 15 16const start = Date.now(); 17 18const slowIOmax = 100; 19let slowIOcount = 0; 20let fastIOdone = false; 21let slowIOend, fastIOend; 22 23function onResolve() { 24 slowIOcount++; 25 if (slowIOcount === slowIOmax) { 26 slowIOend = Date.now(); 27 28 // Conservative expectation: finish disc I/O 29 // at least by when the net I/O completes. 30 assert.ok(fastIOdone, 31 'fast I/O was throttled due to threadpool congestion.'); 32 33 // More realistic expectation: finish disc I/O at least within 34 // a time duration that is half of net I/O. 35 // Ideally the slow I/O should not affect the fast I/O as those 36 // have two different thread-pool buckets. However, this could be 37 // highly load / platform dependent, so don't be very greedy. 38 const fastIOtime = fastIOend - start; 39 const slowIOtime = slowIOend - start; 40 const expectedMax = slowIOtime / 2; 41 assert.ok(fastIOtime < expectedMax, 42 'fast I/O took longer to complete, ' + 43 `actual: ${fastIOtime}, expected: ${expectedMax}`); 44 } 45} 46 47 48for (let i = 0; i < slowIOmax; i++) { 49 // We need to refresh the domain string everytime, 50 // otherwise the TCP stack that cache the previous lookup 51 // returns result from memory, breaking all our Math. 52 dns.lookup(`${randomDomain()}.com`, {}, common.mustCall(onResolve)); 53} 54 55fs.readFile(__filename, common.mustCall(() => { 56 fastIOend = Date.now(); 57 fastIOdone = true; 58})); 59 60function randomDomain() { 61 const d = Buffer.alloc(10); 62 for (let i = 0; i < 10; i++) 63 d[i] = 97 + (Math.round(Math.random() * 13247)) % 26; 64 return d.toString(); 65} 66