You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/*** read with timeout* @param {number | string} fdOrPath* @param {number} size* @param {number} timeout* @param {Object} options* @param {number} [options.blockSize=4096]* @param {string=} options.encoding*/functionreadWithTimeout(fdOrPath,size,timeout,options={}){if(!options)options={};if(typeof(fdOrPath)!='number'){throwError(`reading from path not implemented. fdOrPath must be number`);}if(typeof(size)!='number'){throwError(`invalid size: ${size}`);}size=size|0;// enforce integer sizeif(size<0){// TODO "size == -1" means: read until EOFthrowError(`invalid size: ${size}`);}if(size==0){// for child_process.execSync the default encoding is "buffer"// https://nodejs.org/api/child_process.html#child_processexecsynccommand-optionsif(!options.encoding||options.encoding=='buffer'){returnBuffer.alloc(0);}// FIXME handle "unrecognized character encoding"// If encoding is 'buffer', or an unrecognized character encoding, Buffer objects will be passed to the callback instead.//if (is_unrecognized(options.encoding)) return Buffer.alloc(0);return'';}constblockSizeDefault=4096;// TODO better? 64 * 1024?constblockSize=Math.min(size,(Number(options.blockSize)|0)||blockSizeDefault);if(options.blockSize)deleteoptions.blockSize;if(options.timeout)throwError('dont set options.timeout, use the timeout parameter');constnodeCode=["const {stdout} = require('process');","const {readSync} = require('fs');","const {Buffer} = require('buffer');",`const buf = Buffer.alloc(${blockSize});`,"let done = 0;","const sleep = ms => new Promise(r => setTimeout(r, ms));","async function main() {",` while (done < ${size}) {`,` const n = readSync(${fdOrPath}, buf, 0, ${blockSize}, -1);`," if (n > 0) stdout.write(buf);"," done += n;",// reduce cpu time from 100% to 0%// 200ms is arbitrary, 50ms would be enough to reduce cpu time" await sleep(200);"," }","}","main();",].join('\n');//console.log('nodeCode:\n' + nodeCode); // debugconstnodeExe=process.argv[0];constnodeArgs=['-e',nodeCode];// connect fdOrPath to stdin of the subprocessconststdio=[fdOrPath,'pipe','pipe'];//console.dir({ fdOrPath, size, timeout, stdio, nodeArgs });constreader=child_process.spawnSync(nodeExe,nodeArgs,{
timeout,
stdio,windowsHide: true,
...options,});if(reader.error)throwreader.error;returnreader.stdout;}
i guess we still need child_process.spawnSync to enforce the read timeout
readSync is non-blocking on stdin because stdin is a non-blocking stream
but the jobserver fds or fifo can be blocking, so readSync could hang forever
currently tokenpool.js only works on linux (and probably on macos)
this calls dd to read 1 byte from the jobserver fd
an alternative would be the head command
but
head -c
is not posix-compliantsee also Can I read a single character from stdin in POSIX shell?
(maybe
dd status=none
is also not posix-compliant...)possible solution
if the
dd
andhead
commands are not available, runnode
draft added in 663f117
i guess we still need
child_process.spawnSync
to enforce the read timeoutreadSync
is non-blocking onstdin
becausestdin
is a non-blocking streambut the jobserver fds or fifo can be blocking, so
readSync
could hang foreverthe generated
nodeCode
looks like3 is the fd number to read from, 0 would be stdin
The text was updated successfully, but these errors were encountered: