pm2 not useable in electron production app

Created on 23 Jan 2017  路  22Comments  路  Source: Unitech/pm2

refering to https://github.com/electron/electron/issues/8375#

OS: OSX 10.11.6
node: 6.2.2
pm2: 2.2.3

in the meanwhile i managed to launch pm2 via nodes childprocess.exexFile (programmatic API usage still not possible) - and for some reason the arguments are not being parsed by pm2 if ran in production (electron app bundle) --> PM2 starts up, but the binary.json is not being used so the binary which should be managed by pm2 is not launched.

function launchPM2() { 

  var fpath = path.join(__dirname, '/node_modules/pm2/bin/pm2');
  execFile(fpath, ['start', __dirname+'/binary.json'], (error, stdout, stderr) => {
  if (error) {
    console.log(`exec error: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.log(`stderr: ${stderr}`);
});

}

this works fine unless i run it in production (after packaging the electron application)
any idea what might be wrong or a hint where to look for potential bugs?

Pending Release

Most helpful comment

This may be related to another issue we had where execPath and node were not pointing to the same binary (ie not same node version, leads to broken packages where you've to build).

But, IMO if someone has the above issue, it should be fixed on the target server (ie fix nodejs version conflicts). So :+1: to hard-code it!

All 22 comments

Isn't it possible to launch pm2 programmatically?

The API is documented here btw

Isn't it possible to launch pm2 programmatically?

@soyuka it is. but this only works in dev mode. if packaged for distribution it ends up in a "respwan loop" (without pm2 being launched). same issue described here: http://stackoverflow.com/q/39796945/6486399
that is why i tried the workaround described above..

pm2.connect(function(err) { //start up pm2 god
    if (err) {
      console.error(err);
      process.exit(2);
    }

    var binpath = './path/to/my/binary';
    pm2.start({
    script    : binpath,         
    exec_mode : 'fork',
    cwd: './working_dir/'
    }, function(err, apps) {
       pm2.disconnect();   
       if (err) throw err
    });
});

^ will work in dev mode unless packed for distribution.

could you try adding a false before the callback in the pm2.connect (to launch it in non-daemon mode) ?

@vmarchaud running in noDaemonMode solved the problem. only issue is that pm2 gets killed when the app-process exits. is there a way to _sucessfully_ launch the daemon _(in production mode)_?

Remove the non-daemon mode ^^
Little explaination : when you run pm2 start, it start the daemon if not already started, then connect to it and finally the daemon spawn your process.
So my guess is that the process spawned inside the electron can't access the daemon socket files (~/.pm2/*.sock) in production mode.

@vmarchaud removing the non-daemon mode results in the described misbehaviour. i updated my last question for sake of clearness.

So my guess is that the process spawned inside the electron can't access the daemon socket files (~/.pm2/*.sock) in production mode

any idea how it could be fixed or how to make sure that this is the issue?

(not sure if related to a potential file-access issue) - system log shows multiple entries of:

23.01.17 19:34:29,141 pm2_electron Helper[28834]: GVA info: preferred scaler idx 0
23.01.17 19:34:29,561 launchservicesd[78]: SecTaskLoadEntitlements failed error=22
23.01.17 19:34:29,568 lsd[268]: LaunchServices: Could not store lsd-identifiers file at /private/var/db/lsd/com.apple.lsdschemes.plist

plist file does not exist.

Run electron with DEBUG=pm2:* and paste the whole log here (preferably inside a pastebin)

Re-open if you have more informations

The problem is line 226 in Client.js:

  var child = require('child_process').spawn(process.execPath || 'node', node_args, {

process.execPath isn't the path to a node binary, but rather the path to the electron helper. Thus it can't be used to start pm2.

Fixes could be one of:

  1. Add an override option
  2. Check for path.basename(process.execPath) === 'Electron Helper' and use node instead
  3. Always use node

ping @vmarchaud

Its the daemon code so it isn't related to child process, maybe from here ?

Not sure I understand what you mean... maybe I don't have the exact same issue as the original poster...

This is what I'm doing in an electron process:

const pm2 = require('pm2')

pm2.connect((err) => {
  if (err) throw err

  console.log('Success')
})

The problem is that the callback never gets called. If I step thru the code with the debugger, I can see that it tries to launch the process in Client.js, line 226. Then nothing happens, neither .once('error', ...) or .on('message', ...) is triggered.

If I look into ~/.pm2/pm2.log I can see that:

Error: Cannot find module 'MY_PROJECT_FOLDER/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Resources/electron.asar/browser/init.js'
    at Function.Module._resolveFilename (module.js:455:15)
    at Function.Module._load (module.js:403:25)
    at Module.runMain (module.js:590:10)
    at run (bootstrap_node.js:402:7)
    at startup (bootstrap_node.js:157:9)
    at bootstrap_node.js:521:3

and if I modify .spawn(process.execPath || 'node', ... to .spawn('node', ... it works flawlessly.

My bad, i thought you were explaning that pm2 can't spawn electron process.
So in your case its a problem yeah, can you make a quick PR so i can merge it ?

Absolutely, what approach do you want to take? Check for Electron Helper and use node in that case?

No, we should always spawn the PM2 Daemon with node, so i'm pretty sure you can hardcode it.

This may be related to another issue we had where execPath and node were not pointing to the same binary (ie not same node version, leads to broken packages where you've to build).

But, IMO if someone has the above issue, it should be fixed on the target server (ie fix nodejs version conflicts). So :+1: to hard-code it!

Published under pm2 2.4.3 !

I'm still having this issue. It is working fine in development mode but while packaged, I'm having the following issue:

Error: Cannot find module 'c:\Program Files\MyApp\resources\app.asarnode_modulespm2\lib\Daemon.js'
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3

I have the same problem, same error @LinusU had:

Error: Cannot find module '/private/var/www/credenciando/desktop/app-builds/mac/angular-electron.app/Contents/Frameworks/angular-electron Helper.app/Contents/Resources/electron.asar/browser/init.js'
    at Function.Module._resolveFilename (module.js:543:15)
    at Function.Module._load (module.js:473:25)
    at Function.Module.runMain (module.js:683:10)
    at startup (bootstrap_node.js:196:16)
    at bootstrap_node.js:622:3

Does anyone knows how to get around this?

Anyone could help please?

I fixed this problem by https://github.com/electron/electron/issues/8375

good luck @ndrantotiana @LinusU @vmarchaud @soyuka @matheusdavidson

Was this page helpful?
0 / 5 - 0 ratings