diff --git a/packages/server/timers/child.js b/packages/server/timers/child.js index f57b0d5a64..65a2cc14d6 100644 --- a/packages/server/timers/child.js +++ b/packages/server/timers/child.js @@ -1,20 +1,34 @@ -const log = require('debug')('cypress:server:timers') +const debug = require('debug')('cypress:server:timers:child') +const net = require('net') + +const ipcPath = process.argv.pop() + +const sock = net.createConnection({ + path: ipcPath, +}, () => { + debug('connected to %o', { ipcPath }) +}) + +sock.on('data', (obj = {}) => { + debug('received %o', obj) + obj = JSON.parse(obj.toString()) -process.on('message', (obj = {}) => { const { id, ms } = obj - log('child received timer id %d', id) + debug('child received timer id %d', id) setTimeout(() => { try { - log('child sending timer id %d', id) - - // process.send could throw if - // parent process has already exited - process.send({ + const outObj = JSON.stringify({ id, ms, }) + + debug('child sending timer id %d %o', id, outObj) + + // process.send could throw if + // parent process has already exited + sock.write(outObj) } catch (err) { // eslint-disable no-empty } diff --git a/packages/server/timers/parent.js b/packages/server/timers/parent.js index bd44be7467..9726c25a3a 100644 --- a/packages/server/timers/parent.js +++ b/packages/server/timers/parent.js @@ -8,7 +8,9 @@ const cp = require('child_process') const path = require('path') -const log = require('debug')('cypress:server:timers') +const debug = require('debug')('cypress:server:timers:parent') +const net = require('net') +const os = require('os') const st = global.setTimeout const si = global.setInterval @@ -39,7 +41,7 @@ function fix () { function sendAndQueue (id, cb, ms, args) { // const started = Date.now() - log('queuing timer id %d after %d ms', id, ms) + debug('queuing timer id %d after %d ms', id, ms) queue[id] = { // started, @@ -62,32 +64,58 @@ function fix () { } function clear (id) { - log('clearing timer id %d from queue %o', id, queue) + debug('clearing timer id %d from queue %o', id, queue) delete queue[id] } // fork the child process - let child = cp.fork(path.join(__dirname, 'child.js'), [], { + let ipc = net.createServer() + const ipcPath = path.join(os.tmpdir(), `cy-timers-${Math.random().toString()}`) + + debug('listening on %o', { ipcPath }) + + let child = cp.spawn('node', [ + path.join(__dirname, 'child.js'), + ipcPath, + ], { stdio: 'inherit', }) - .on('message', (obj = {}) => { - const { id } = obj - const msg = queue[id] + ipc.listen({ + path: ipcPath, + }) - // if we didn't get a msg - // that means we must have - // cleared the timeout already - if (!msg) { - return + ipc.on('connection', (sock) => { + debug('connection received') + child.send = (obj) => { + obj = JSON.stringify(obj) + debug('sending %o', { obj }) + + return sock.write(obj) } - const { cb, args } = msg + sock.on('data', (obj = '{}') => { + debug('received %o', { obj: obj.toString() }) + obj = JSON.parse(obj.toString()) - clear(id) + const { id } = obj - cb(...args) + const msg = queue[id] + + // if we didn't get a msg + // that means we must have + // cleared the timeout already + if (!msg) { + return + } + + const { cb, args } = msg + + clear(id) + + cb(...args) + }) }) // In linux apparently the child process is never