Phantom instances



  • I am using jsreport-core to convert html to pdf and send the pdf by email.

    My structure is the following:

    var jsreport = require ('jsreport-core') ();
    
    var contentPDF = '<html> <body> hello world and other things ... </ body> </ html>';
    
    jsreport.init (). then (function () {
        return jsreport.render ({
          template: {
            content: contentPDF,
            engine: 'none',
            recipe: 'phantom-pdf'
          }
        })
    });
    

    I have a service on my server that runs every so often, generates the reports that I have to generate and sends them, but I'm having problems with my server because phantom creates several instances and consumes a lot of memory and causes my server to die.

    I'm trying to use something like this:

    var jsreport = require ('jsreport-core') ();
    jsreport.use (require ('jsreport-phantom-pdf') ({"numberOfWorkers": 1, "strategy": "phantom-server"}));
    

    but it seems to have no effect; Do you have any suggestions or help that you can give me? Is that the solution or is there something that is ignoring or doing wrong?

    I appreciate the help you can give me.



  • This initialization should result in using single phantomjs worker. Try to print logs to console.
    For example by setting this at the top of your file.

    process.env.debug = 'jsreport'
    


  • Or write some debug information here .



  • I'm not good at debugging, but checking the phantomManager.js file I could verify that if the parameters are being passed and Phantom creates the instances that I configured.

    var PhantomManager = module.exports = function (options) {
    this._phantomInstances = [];
    this.options = options || {};
    this.options.workerEnv = this.options.workerEnv || {};
    this.options.numberOfWorkers = this.options.numberOfWorkers || numCPUs;
    console.log('PhantomManager this.options.numberOfWorkers ', this.options.numberOfWorkers);//log*************
    this.options.timeout = this.options.timeout || 180000;
    this.options.host = this.options.host || "127.0.0.1";
    this.options.hostEnvVarName = this.options.hostEnvVarName || "PHANTOM_WORKER_HOST"
    this.options.portEnvVarName = this.options.portEnvVarName || "PHANTOM_WORKER_PORT";
    this._timeouts = [];
    this.tasksQueue = [];
    };

    The problem is that you are not deleting those instances or reusing them, simply create new ones, which leaves my server without memory. I believe that with the kill method it removes the instances when the process ends:

    process.once("exit", function () {
    self.kill();
    });

    But he is not eliminating them. Help me please.



  • Do you call jsreport.init just once? The instances should be reused if you do.



  • That said, that would be the problem. Then I ask for your help or advice in this regard; This is what my service does:

    I do not want to schedule tasks in the cron of my server, so I created a service in NodeJs using cronjs library, which runs every hour and check in the database the reports that are scheduled at that time, I go through the elements of the I list one by one and for each report I execute the jsreport.init method, I create the report and send it, and every hour I do the same.

    var job = new CronJob ({
    cronTime: '0 0 * * * *',
    onTick: function () {
        login()
        .then (getScheduledReports)
        .then (function (data) {
            data.reduce (function (promise, schReport) {
    
                // This is where I run the jsreport.init method and the code is similar to this one, please ignore the indentation and other details (hehe).
    
                jsreport.init (). then (function () {
                    return jsreport.render ({
                      // parameters
                    }). then (sendMail)
                });
    
            }, new Q ());
        }
    },
    start: true,
    timeZone: 'America / Bogota'
    });
    job.start ();
    


  • You should initialize jsreport just once. In the outer scope somewhere. Then call just jsreport.render.
    I don't understand why you call init every time, can you elaborate on it?



  • I think I had a bad interpretation. I thought that the init method should be executed every time you want to render a report.



  • No, just once. Otherwise it would part of the render.
    There is quite heavy code running inside init and that is why it is extracted.


Log in to reply
 

Looks like your connection to jsreport forum was lost, please wait while we try to reconnect.