try: using system node for the timers, setting up our own IPC

This commit is contained in:
Zach Bloomquist
2019-06-11 12:22:38 -04:00
parent aee8a7271d
commit c51b3957e2
2 changed files with 65 additions and 23 deletions

View File

@@ -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
}

View File

@@ -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