PhantomJS Instance is not destroyed when it is more than maximum instances
I am running the phantom pool to maintain the instances of the phantomJS with
const pool = phantomPool.default({ max: 100, // default min: 20, // default // how long a resource can stay idle in pool before being removed idleTimeoutMillis: 30000, // default. // maximum number of times an individual resource can be reused before being destroyed; set to 0 to disable maxUses: 50, // default // function to validate an instance prior to use; see https://github.com/coopernurse/node-pool#createpool validator: () => Promise.resolve(true), // defaults to always resolving true // validate resource before borrowing; required for maxUses and validator
testOnBorrow: true, // default
// For all opts, see opts at https://github.com/coopernurse/node-pool#createpool
phantomArgs: [['--ignore-ssl-errors=true', '--disk-cache=true'], {
logLevel: 'info',
}], // arguments passed to phantomjs-node directly, default is []. For all opts, see https://github.com/amir20/phantomjs-node#phantom-object-api
})`
I run the application after sometime the number of phantom instances is going beyond 100(which is the maximum)
how do you use the instances exactly though? can u share your code?
[phantom-pool.js.txt](https://github.com/blockai/phantom-pool/files/888174/phantom-pool.js.txt)
* Phantom Server to serve requests for Google Crawlers.
* Requires Phantom JS installation.
* Requires Express JS Installation
* Command to Execute: node <location>\angular-seo-server.js <portNumber for node express server> <redirecte URL Prefix>
* Example: node angular-seo-server.js 8090 http://www.mywebsite.com
*/
//var system = require('system');
//var server = require('webserver').create();
var express = require('express');
var phantom = require("phantom");
var winston = require('winston');
var phantomPool = require('phantom-pool');
var app = express();
//console.log("phantomPool", phantomPool);
//var port = parseInt(system.args[1]);
//var urlPrefix = system.args[2];
// process.argv.forEach(function (index, val){
// winston.info(`${index}: ${val}`);
// });
var port = process.argv[2];
var urlPrefix = process.argv[3];
for(var key in phantomPool){
console.log("key", key);
}
// Returns a generic-pool instance
const pool = phantomPool.default({
max: 40, // default
min: 30, // default
// how long a resource can stay idle in pool before being removed
idleTimeoutMillis: 30000, // default.
// maximum number of times an individual resource can be reused before being destroyed; set to 0 to disable
maxUses: 50, // default
// function to validate an instance prior to use; see https://github.com/coopernurse/node-pool#createpool
validator: () => Promise.resolve(true), // defaults to always resolving true
// validate resource before borrowing; required for `maxUses and `validator`
testOnBorrow: true, // default
// For all opts, see opts at https://github.com/coopernurse/node-pool#createpool
phantomArgs: [['--ignore-ssl-errors=true', '--disk-cache=true'], {
logLevel: 'info',
}], // arguments passed to phantomjs-node directly, default is `[]`. For all opts, see https://github.com/amir20/phantomjs-node#phantom-object-api
})
//pool = new Object();
var parse_qs = function(s) {
/*var queryString = {};
var a = document.createElement("a");
a.href = s;
a.search.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
return queryString;*/
var vars = {}, hash;
var hashes = s.slice(s.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
//vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
winston.info('vars', vars);
return vars;
};
var renderHtml = function(url, cb) {
var _ph, _page, _content;
// phantom.create().then(function(ph) {
// _ph = ph;
// return _ph.createPage();
// }).then(function(page) {
// _page = page;
// // _page.setting('loadImages', false);
// // _page.setting('localToRemoteUrlAccessEnabled', true)
// // _page.setting('userAgent', "msie 9.0 Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53");
// // _page.property('customHeaders', {
// // "User-Agent": "msie 9.0 Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53"
// // });
// winston.info(new Date() + ": URL to Open", url);
// return _page.open(url);
// }).then(function(status) {
// winston.info('status: ' + status)
// //winston.info(status);
// return _page.property('content')
// }).then(function(content) {
// _content = content;
// //setTimeout(function() {
// cb(_content);
// _page.close();
// _ph.exit();
// //}, 3000);
// }).catch(e => winston.info(e));
pool.use(function(instance) {
_ph = instance;
return instance.createPage()
}).then(function(page) {
_page = page;
// _page.setting('loadImages', false);
// _page.setting('localToRemoteUrlAccessEnabled', true)
// _page.setting('userAgent', "msie 9.0 Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53");
// _page.property('customHeaders', {
// "User-Agent": "msie 9.0 Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53"
// });
winston.info(new Date() + ": URL to Open", url);
return _page.open(url);
}).then(function(status) {
winston.info('status: ' + status)
//winston.info(status);
return _page.property('content')
}).then(function(content) {
return content;
}).then((content) => {
_content = content;
//setTimeout(function() {
cb(_content);
_page.close();
//_ph.exit();
//}, 3000);
}).catch(e => winston.info(e));
};
app.listen(port, function() {
winston.info("Server is up ...")
});
app.all("*", function (request, response) {
winston.info(new Date() + ": Original URL", request.originalUrl);
var route = parse_qs(request.originalUrl)._escaped_fragment_;
var url;
winston.info("route", route);
if (route) {
//url = urlPrefix
//+ request.url.slice(1, request.url.indexOf('?'))
//+ '#!' + decodeURIComponent(route);
url = urlPrefix
+ decodeURI(request.originalUrl);
} else if (request.originalUrl.indexOf("_escaped_fragment_") > -1) {
//url = urlPrefix + "/web/home";
url = urlPrefix
+ decodeURI(request.originalUrl);
} else {
url = urlPrefix
+ decodeURI(request.originalUrl);
}
url = url.replace("_escaped_fragment_", "_escaped_good_fragment_");
/*var url = urlPrefix
+ request.url.slice(1, request.url.indexOf('?'))
+ '#!' + decodeURIComponent(route);*/
renderHtml(url, function(html) {
response.set("Content-Type", "text/html")
response.status(200).send(html);
winston.info(new Date() + ": response: " + url, "committed");
});
});
winston.info(new Date() + ': Listening on ' + port + '...');
winston.info('Press Ctrl+C to stop.');
I have pasted the code. One more issue is memory for the each phantom instance is growing over GBs making the server crash.
well PhantomJS is really known for it's memory leaks, so I wouldn't be surprised with that. By the way you don't seem to be resolving anything in the pool.use chain and i guess that's the issue with instances not being destroyed and growing beyond max number of instances allowed. If you read the docs it is stated that the instances will have their pool-based behavior if "something" gets resolved OR an error is thrown. i would suggest going through https://github.com/coopernurse/node-pool too, you may get some clarification.