Node.js Cluster with JSReport



  • Can I deploy JSReport in a cluster? I tried the following way, but failed.

    if (cluster.isMaster) {
        let cpuCount = require('os').cpus().length;
        for (let i=0; i<cpuCount; i++) {
            cluster.fork();
        }
        cluster.on('fork', (wkr) => {
            console.log(`Worker ${wkr.id} is forked.`)
        });
        cluster.on('exit', (wkr, code, signal) => {
            console.error(`Worker ${wkr.id} died ${signal || code}`);
        });
    } else {
        let server = app.listen(svcConfig.port, () => {
            console.log('Process ' + process.pid + ' is listening to all incoming requests');
        });
        let jsreport = require('jsreport')({
            express: { app :reportingApp, server: server },
            appPath: "/reporting"
        });
        jsreport.init().catch(function (e) {
            console.error(e);
        });
        app.use('/reporting', reportingApp);
        app.get('/',  (req, res) => {
            res.send('Hello from the main application');
        });
    }
    

    Any help is really appreciated!


  • administrators

    hi! you need to call jsreport.init after the server has started.

    updated code:

    'use strict';
    
    var cluster = require('cluster');
    
    if (cluster.isMaster) {
      let cpuCount = require('os').cpus().length;
    
      cluster.on('fork', wkr => {
        console.log(`Worker ${wkr.id} is forked.`);
      });
    
      cluster.on('exit', (wkr, code, signal) => {
        console.error(`Worker ${wkr.id} died ${signal || code}`);
      });
    
      for (let i = 0; i < cpuCount; i++) {
        cluster.fork();
      }
    } else {
      let express = require('express');
      let app = express();
      let reportingApp = express();
      let server;
    
      app.use('/reporting', reportingApp);
    
      app.get('/', (req, res) => {
        res.send('Hello from the main application');
      });
    
      server = app.listen(9500, () => {
        console.log(
          'Process ' + process.pid + ' is listening to all incoming requests'
        );
    
        let jsreport = require('jsreport')({
          express: { app: reportingApp, server: server },
          appPath: '/reporting'
        });
    
        jsreport
          .init()
          .then(() => {
            console.log('jsreport instance ' + process.pid + ' started correctly');
          })
          .catch(function(e) {
            // error during startup
            console.error(e.stack);
          });
      });
    }
    

    NOTE: remember that jsreport by default uses fs store, which read and write templates from file system, which may not work well when using cluster mode because at some point multiple processes will try to access the files at the same time and that could causes unexpected errors, when you use cluster try to use another store like mongodb-store to avoid those possible problems



  • @bjrmatos Thank you so much! Let me try the MongoDB store.


Log in to reply
 

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