jsreport / jsreport-core

The minimalist jsreport rendering core
GNU Lesser General Public License v3.0
86 stars 24 forks source link

jsreport-core does not exit #5

Closed jleach closed 8 years ago

jleach commented 8 years ago

I tried the example form the README. While it works fine at creating a PDF the script does not exit. Is there something in jsreport-core that holds the process so it can not exit? I'm using node.js v4.4.0.

bjrmatos commented 8 years ago

what are the extensions that you have installed?

jleach commented 8 years ago

This is the script I'm running:

const jsrcore = require("jsreport-core");
const phantom = require("jsreport-phantom-pdf");
const renderer = require("jsreport-jsrender");
// const jsreport = jsrcore({ tasks: { strategy: 'in-process',  allowedModules: '*' } });
const jsreport = jsrcore({ tasks: { strategy: 'in-process',  allowedModules: '*' } });

jsreport.init().then(function () {
    jsreport.render({
        template: {
            content: '<h1>Hello {{:foo}}</h1>',
            engine: 'jsrender',
            recipe: 'phantom-pdf'
        },
        data: {
            foo: "world"
        }
    }).then(function(resp) {
        //prints pdf with headline Hello world
        console.log("done");
    });
}).catch(function(e) {
    console.log(e)
});

This is the console output:

(node)Jasons-MacBook-Pro:libs jleach$ node test.js 
done

At this point I have to press Control-C to get node to exit. Note it doesn't make any difference if I remove the prams { tasks: { strategy: 'in-process', allowedModules: '*' } }. The only other related module I have installed (but I'm not loading it) is the version of jsreport-jade that was updated today. I have quite a few other node modules but I'm not loading them.

(node)Jasons-MacBook-Pro:libs jleach$ node -v
v4.4.0
bjrmatos commented 8 years ago

@jleach jsreport-core does not exit because we have some logic to clean old temporal files (used in template rendering).

@pofider i think we should expose a way to disable the temporal files reaper, letting the responsibility to the user

jleach commented 8 years ago

@bjrmatos I think it would be useful if the default behaviour is to exit and cleanup automatically. For those who want to to remain persistent add an option like keepAlive: true. If this is a problem for jsreport then reverse the default so that it remains persistent.

pofider commented 8 years ago

@bjrmatos Yes, that is the partially the reason. However there are also other setTimeout functions checking the timeout in the script-manager which blocks the process exitting.

@jleach Cleanup and process exitting should be both default. I think we can achieve both at once.

Technically we can just call unref on timer which is cleaning up temorary files. Secondary we need to make sure that script-manager is correctly clearing all timers and exitting child processes. Then we should have node process exitting correctly and also having the auto cleanup.

Additionally we add option like autoTempCleanup=true.

bjrmatos commented 8 years ago

@pofider thats a great solution!!! I had forgotten the existence of timer.unref!

3goats commented 8 years ago

Hi,

Has this autoTempCleanup=true option now been implemented? I'm still having problems with the process not existing. However, this only seems to happen when I use the the scripts option.

var jsreport = require('jsreport-core')()
//jsreport.use(require('jsreport-electron-pdf')({ strategy: 'electron-ipc' }));

var fs = require('fs');
//var data = fs.readFileSync('content.handlebars');
var path = require('path');
// make sure to pass the path to your `helper.js`
var helpers = fs.readFileSync(path.join('/Development/jsreport-new/data/templates/Sample report', 'helpers.js'), 'utf8');

var data = fs.readFileSync(path.join('/Development/jsreport-new', 'scratch.json').toString(), 'utf8');
var json = JSON.parse(data);
console.log(json);

jsreport.init().then(function () {
    jsreport.render({
        template: {
            scripts: [{
                content: "request.data=json; done()"
            }],
            content: fs.readFileSync(path.join('/Development/jsreport-new/data/templates/Sample report', 'content.handlebars'), 'utf8'),
            helpers: helpers,
            engine: 'handlebars',
            recipe: 'phantom-pdf',
            phantom: {
                "orientation": "portrait",
                "format": "A3",
                "margin": "3cm",
                "headerHeight": "3cm"
            },
        },
        data: {
            "books": [
                {"name": "A Tale of Two Cities", "author": "Charles Dickens", "sales": 351},
                {"name": "The Lord of the Rings", "author": "J. R. R. Tolkien", "sales": 125},
                {"name": "The Da Vinci Code", "author": "Dan Brown", "sales": 255},
                {"name": "The Hobbit", "author": "J. R. R. Tolkien", "sales": 99},
                {"name": "Carlskii", "author": "J. R. R. Tolkien", "sales": 99}
            ]
        }
    }).then(function(resp) {
        //prints pdf with headline Hello world
        console.log(resp.content.toString())
        resp.result.pipe(fs.createWriteStream('helloworld4.pdf'));
        setTimeout(function() {
            process.exit();
        }, 6000)
    });
}).catch(function(e) {
    console.log(e)
});
pofider commented 8 years ago

@carlskii The issue is open => it is not yet implemented.

Looking at your code....

  1. You don't return promise from jsreport.render , so you loose the thrown error
  2. Your script "request.data=json; done()" is causing the error because global json variable is unknown for the script

I think you have rather problems with script execution (https://github.com/jsreport/jsreport/issues/205) than with process exitting

3goats commented 8 years ago

OK so I'm returning an error now. What should the string be to return data back to the template.

This "request.data='hello'; done();" returns an error:

[Error: Error during rendering report: Unexpected token h]

metachris commented 8 years ago

The reaper can be disabled by monkeypatching the function:

const JSReporter = require("jsreport-core/lib/reporter");
const rep = new JSReporter();
rep._startReaper = function() { /* foo */ };
return rep.init();

This makes the script exit after calling rep.init() when render() is not invoked. When calling render(), the script is still not exiting...

pofider commented 8 years ago

Fixed and released in 0.6.4

metachris commented 8 years ago

Still not exiting for me using 0.6.4

pofider commented 8 years ago

@metachris I assume this is happening only on phantom-pdf recipe, right? I found the bug in it now, if you confirm, I'll release hotfix.

metachris commented 8 years ago

yes thats correct, it only happens with phantom-pdf, not with handlebars.

pofider commented 8 years ago

I released jsreport-phantom-pdf@0.4.4 which should fix it. @metachris Thank you for info

metachris commented 8 years ago

I can confirm that this works now for me