Child process not killed - Node js ( inside Electron js app, windows) - javascript

I am trying to stop this command after 4 seconds, but it doesn't stop the child-process
(Running in an electron-js app, windows )
child = child_process.spawn("ping google.com -t", {
encoding: 'utf8',
shell: true
});
child.stdout.on('data', (data) => {
//Here is the output
data=data.toString();
console.log(data)
});
setTimeout(function() {
console.log('Killing Your child', child.pid);
child.kill()
}, 4 * 1000);
the timeout runs after 4 seconds, it logs the message but never stops the process
I tried using tags inside the kill() like "SIGINT" or "SIGKILL"
I tried running without the timeout too...

By looking at the official documentation for child process I have slightly modified your provided example to a bare minimum of what still seems to work for me. Please note that the ping -t flag requires an argument which you didn't provide.
The following worked for me (the program exits after 4 pings) on Node LTS (16.15.1) and the latest version (18.4.0):
const { spawn } = require('child_process');
const child = spawn("ping", ['www.google.com'], {});
child.stdout.on('data', (data) => { console.log(data.toString()); });
setTimeout(() => {
console.log('Killing Your child', child.pid);
child.kill();
}, 4000);

shell: true doesn't work with .kill()
as you can see in the answer from this post:
Try to kill a spawn process with shell true and detached true nodejs
I needed to replace:
child.kill()
with
child_process.spawn("taskkill", ["/pid", child.pid, '/f', '/t']);

Related

Cypress command timeout of '10000ms' exceeded

Getting started with Cypress, I'm noticing my test fails about passing:
describe('Sessions Page', () => {
it('Loads', () => {
// Set up alias
cy.server()
.route('POST', '/graphql')
.as('graphql');
// Visit site
cy.visit('/', { timeout: 30000 })
.wait('#graphql')
.its('Status')
.should('be', 200);
});
});
When I run this, it passes, then after a few seconds it fails.
I see this output:
Another thing I found strange is that the test says Passed immediately but it's still waiting for the route to resolve:

Node.js - Get used memory of executed app (even after it has been killed)

How can I take memory usage of ChildProcess even after it was killed (in exec callback)?
I tried using the pidusage module, but it only works when the process is opened.
What I actually tried:
var proc = exec(execComm,(error, stdout, stderr) => {
if (error) {
callback({status: -1, reason:stderr });
}
var pidusage = require("pidusage");
pidusage(proc.pid,function(err,stat){
console.log(err,stat);
});
callback({ status:0, file: out });
});
But why does pidusage send [Error: No maching pid found]?
Is it because this module can't get info of the already closed one?
And how to get that info in the exec callback?
You could bind a helper to the exit signal of your app and read out memory usage then but since the gc will likely run on unpredictable times I'm not sure what use you get out of that.
const ExitHandler = () => { /* your code */ };
process.on( 'exit', ExitHandler.bind( null, { withoutSpace: false } ) ); // on closing
process.on( 'SIGINT', ExitHandler.bind( null, { withoutSpace: true } ) ); // on [ctrl] + [c]
process.on( 'uncaughtException', ExitHandler.bind( null, { withoutSpace: false } ) ); // on uncaught exceptions
I belive you could use something like node-heapdump to create heapdumps in your child-processes that you could inspect after the fact.
That way you could also have multiple dumps so you could inspect the memory usage over time.

error: Error: Stale RTM connection, closing RTM; rtm_close event not triggered

I have created a basic bot and left it connected. After some time, it gave the error Stale RTM connection, closing RTM. The rtm_close event was not fired and the process is still running then why did the bot stop listening.
How to deal with such issues in production? Why is rtm_close event not fired?
Environment:
Current version: "version": "0.5.4" (from botkit package.json)
OS: macOS Sierra (version: 10.12.4)
Simple code:
function rtmManager(controller, config) {
var bot = controller.spawn(config);
bot.startRTM(function(err, bot) {
if (err) {
debug('Failed to start RTM')
}
} );
controller.on('rtm_close', function(bot) {
debug('RTM connection is closed');
});
return bot;
}
var Botkit = require('botkit');
var bot_options = {
debug : process.env.DEBUG || false,
};
var controller = Botkit.slackbot(bot_options);
controller.startTicking();
rtmManager(controller, {token: process.env.SLACK_TOKEN});
In fact, rtm_close callback is invoked but it was throwing an error which is no where caught. So, it seems not called.

How to monitor HTTP calls using browsermob-proxy and nightwatch.js?

I am writing testcases using Nightwatch.js framework for SPA application. A requirement came in here we have to monitor HTTP calls and get the performance results for the site. As this could be easily achieved using JMeter.
Using automation testing tool, we can do it by using browsermob-proxy and selenium.
Is it possible to do the same using Nightwatch.js and browsermob-proxy?
Also what are the steps to do to the same.
For using Nightwatchjs and browsermob-proxy together, check out this repo, which includes info on the NodeJS bindings for browsermob-proxy and programmatically generating HAR (HTTP Archive) files.
If you're content with just using Nightwatchjs, this repo has code in the tests directory for the following:
Custom command to get the requests made so far
Custom assertion for checking if a request, given a filter and query string params, exists.
You might have to brush up on how to add custom commands and assertions to your Nightwatch project, but after that you should be set to go!
You can use browsermob-proxy-api
just simply download browsermob-proxy server then
install by npm command: npm install browsermob-proxy-api --save-dev
configure you night watch like this in desiredCapabilites:
'test_settings': {
'default': {
'launch_url': 'http://localhost:3000',
'screenshots': {
'enabled': true, // if you want to keep screenshots
'path': './screenshots' // save screenshots here
},
'globals': {
'waitForConditionTimeout': 30000 // sometimes internet is slow so wait.
},
'desiredCapabilities': { // use Chrome as the default browser for tests
'browserName': 'chrome',
'proxy': {
'proxyType': 'manual',
'httpProxy': 'localhost:10800'
},
'acceptSslCerts': true,
'javascriptEnabled': true, // turn off to test progressive enhancement
}
},
then download index.js from here:
https://github.com/jmangs/node-browsermob-proxy-api
and add code from example to your step_definitions if you use gherkin or describe step
Bit late into dance. I managed to integrate browsermob to nightwatch. Here are the detailed steps
Download browsermob proxy https://bmp.lightbody.net/
Open your cmd and go to bin folder and then start browsermob using "browsermob-proxy".
I am assuming you have basic nightwatch setup. You also need mobproxy. Install it from "npm i browsermob-proxy-api"
Create a global hook in nightwatch. Say 'globalmodule.js' and give this file path in globals_path in nightwatch.json
In globalmodule, create global hooks as described in http://nightwatchjs.org/guide#external-globals
In beforeEach hook, add below code: //if you are not under corporate proxy and you dont need to chain to upstream proxy
var MobProxy = require('browsermob-proxy-api');
var proxyObj = new MobProxy({'host': 'localhost', 'port': '8080'});
//assuming you started browsermob in 8080 port. That is in step 2.
//if you are working under corporate proxy, you might have to chain your request. This needs editing in browsermob-proxy-api package. Follow steps given at end of this section.
Start proxy on new port
proxyObj.startPort(port, function (err, data) {
if (err) {
console.log(err);
} else {
console.log('New port started')
}
})
Once we have new port, we have to start our chrome browser in above port so that all browser request are proxied through browsermob.
proxyObj.startPort(port, function (err, data) {
if (err) {
console.log(err);
} else {
console.log('New port started')
var dataInJson = JSON.parse(data);
//Step 8:
this.test_settings.desiredCapabilities = {
"browserName": "chrome",
"proxyObj": proxyObj, //for future use
"proxyport": dataInJson.port, //for future use
"proxy": {
"proxyType": "manual",
"httpProxy": "127.0.0.1:" + dataInJson.port,
"sslProxy": "127.0.0.1:" + dataInJson.port //important is you have https site
},
"javascriptEnabled": true,
"acceptSslCerts": true,
"loggingPrefs": {
"browser": "ALL"
}
}
}
})
Try to run with above setting, you can check if cmd [created in step2 to confirm request are going via above port. There will be some activiy]
For creating HAR and getting created HAR, browsermob-proxy-api gives excellent api.
add createHAR.js in any path and mention that path in nightwatch.json[custom_commands section]
exports.command = function (callback) {
var self = this;
if (!self.options.desiredCapabilities.proxyObj) {
console.error('No proxy setup - did you call setupProxy() ?');
}
this.options.desiredCapabilities.proxyObj.createHAR(this.options.desiredCapabilities.proxyport, {
'captureHeaders': 'true',
'captureContent': 'true',
'captureBinaryContent': 'true',
'initialPageRef': 'homepage'
}, function (err, result){
if(err){
console.log(err)
}else{
console.log(result)
if (typeof callback === "function") {
console.log(this.options.desiredCapabilities.proxyObj);
console.log(this.options.desiredCapabilities.proxyport);
// console.log(result);
callback.call(self, result);
}
}
});
return this;
};
then to getHAR, add getHAR.js, add below code.
var parsedData;
exports.command = function(callback) {
var self = this;
if (!self.options.desiredCapabilities.proxy) {
console.error('No proxy setup - did you call setupProxy() ?');
}
self.options.desiredCapabilities.proxyObj.getHAR(self.options.desiredCapabilities.proxyport, function (err, data) {
console.log(self.options.desiredCapabilities.proxyObj);
console.log(self.options.desiredCapabilities.proxyport);
//console.log(result);
if(err){
console.log(err)
}else{
parsedData = JSON.parse(data)
console.log(parsedData.log.entries)
}
if (typeof callback === "function") {
console.log(self.options.desiredCapabilities.proxyObj);
console.log(self.options.desiredCapabilities.proxyport);
callback.call(self, parsedData);
}
});
return this;
};
At start of test, createHAR will not have proxyObj, So this step should be executed sync. Wrap that step with browser.perform()
browser.perform(function(){
browser.createHAR()
})
////some navigation
browser.perform(function(){
browser.getHAR()
})
Note: If you are working behind corporate proxy, You might have to use chain proxy piece which browsermob offers.
According to browsermob proxy documentation, get down to api section, -> /proxy can have request parameters "proxyUsername" and "proxyPassword"
In node_modules->browsermob-proxy-api->index.js
add below line after line 22:
this.proxyUsername = cfg.proxyUsername || '';
this.proxyPassword = cfg.proxyPassword || '';
this.queryString = cfg.queryString || 'httpProxy=yourupstreamProxy:8080'; //you will get this from pac file
then at line 177, where package is making request '/proxy' to browser.
replace
path: url
to
path: url + '?proxyUsername=' +this.proxyUsername + '&proxyPassword=' + this.proxyPassword + '&' + this.queryString

Gruntfile getting error codes from programs serially

I want to create a grunt file that runs 3 grunt tasks serially one after another regardless of whether they fail or pass. If one of the grunts task fails, I want to return the last error code.
I tried:
grunt.task.run('task1', 'task2', 'task3');
with the --force option when running.
The problem with this is that when --force is specified it returns errorcode 0 regardless of errors.
Thanks
Use grunt.util.spawn: http://gruntjs.com/api/grunt.util#grunt.util.spawn
grunt.registerTask('serial', function() {
var done = this.async();
var tasks = {'task1': 0, 'task2': 0, 'task3': 0};
grunt.util.async.forEachSeries(Object.keys(tasks), function(task, next) {
grunt.util.spawn({
grunt: true, // use grunt to spawn
args: [task], // spawn this task
opts: { stdio: 'inherit' }, // print to the same stdout
}, function(err, result, code) {
tasks[task] = code;
next();
});
}, function() {
// Do something with tasks now that each
// contains their respective error code
done();
});
});

Categories

Resources