Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't spawn `gcloud app deploy` from a Node.js script on Windows

I'm building an Electron application (Node.js) which needs to spawn gcloud app deploy from the application with realtime feedback (stdin/stdout/stderr).

I rapidly switched from child_process to execa because I had some issues on Mac OS X with the child_process buffer which is limited to 200kb (and gcloud app deploy sends some big chunk of string > 200kb which crash the command).

Now, with execa everything seems to work normally on OSX but not on Windows.

The code looks something like this:

let bin = `gcloud${/^win/.test(process.platform) ? '.cmd' : ''}`

//which: https://github.com/npm/node-which
which(bin, (err, fullpath) => {
  let proc = execa(fullpath, ['app', 'deploy'], {
    cwd: appPath
  })
  proc.stdout.on('data', data => {
    parseDeploy(data.toString())
  })
  proc.stderr.on('data', data => {
    parseDeploy(data.toString())
  })
  proc.then(() => {
    ...
  }).catch(e => {
    ...
  })
})

This code works perfectly on Mac OS X while I haven't the same result on Windows

I have tried lots of thing:

  • execa()
  • execa.shell()
  • options shell:true
  • I tried maxBuffer to 1GB (just in case)
  • It works with detached:true BUT I can't read stdout / stderr in realtime in the application as it prompts a new cmd.exe without interaction with the Node.js application
  • Lots of child_process variant.

I have made a GIST to show the responses I get for some tests I have done on Windows with basic Child Process scripts: https://gist.github.com/thyb/9b53b65c25cd964bbe962d8a9754e31f

I also opened an issue on execa repository: https://github.com/sindresorhus/execa/issues/97

Does someone already got this issue ? I've searched around and found nothing promising except this reddit thread which doesn't solve this issue.

like image 797
Thibaud Arnault Avatar asked Jun 29 '17 08:06

Thibaud Arnault


People also ask

Does Google Cloud support Nodejs?

Google Cloud lets you choose the best environment to run your Node. js applications, with options for serverless, Kubernetes, VMs, or custom hardware.

How long does gcloud app deploy take?

When firing of gcloud preview app deploy the whole process takes ~8 minutes, most of which is "updating service".


1 Answers

Behind the scene, gcloud.cmd is running a python script. After reading tons of Node.js issue with ChildProcess / Python and Windows, I fell on this thread: https://github.com/nodejs/node-v0.x-archive/issues/8298

There is some known issue about running Python scripts from a Node.js Child Process. They talk in this comment about an unbuffered option for python. After updating the shell script in gcloud.cmd by adding the -u option, I noticed everything was working as expected

This comment explains how to set this option as an environment variable (to not modify the windows shell script directly): https://docs.python.org/2/using/cmdline.html#envvar-PYTHONUNBUFFERED

So adding PYTHONUNBUFFERED to the environment variable fix this issue !

execa(fullpath, ['app', 'deploy'], {
  cwd: appPath,
  env: Object.assign({}, process.env, {
    PYTHONUNBUFFERED: true
  })
})
like image 166
Thibaud Arnault Avatar answered Oct 31 '22 17:10

Thibaud Arnault