-
Notifications
You must be signed in to change notification settings - Fork 640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maximum call stack size exceeded when include many templates #787
Conversation
} | ||
}, | ||
|
||
waterfall: waterfall |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt that it's good enough way to include a lib code into compiled template. Please feel free to suggest a better one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an issue with this if it works :-) What downside do you see that prompted this comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be a static(class) method. But now it's an instance method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eh, in JS the distinction is pretty murky anyway (just a matter of this
binding). Doesn't bother me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok then :-)
Thanks for looking into this! What is the impact on compiled template size? And it looks like tests are failing on some currently-supported Node versions; is this fixable? |
In my project i got 210 templates 530Kb uncompiled. Yeah i'll check tests |
This reverts commit 56e085b.
Stabilised tests. |
This is looking pretty good to me! It's a significant change, so I wouldn't mind another pair of eyes on it. @ricordisamoa @SamyPesse @oyyd ? |
@@ -6,7 +6,8 @@ | |||
"dependencies": { | |||
"asap": "^2.0.3", | |||
"chokidar": "^1.0.0", | |||
"yargs": "^3.32.0" | |||
"yargs": "^3.32.0", | |||
"a-sync-waterfall": "^1.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to sort dependencies alphabetically
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
I left a minor comment but my knowledge of Nunjucks internals is not good enough to review otherwise |
@SamyPesse Let me know if you'll have a chance to take a look at this and test it out anytime soon. I'd like your perspective on it since you were working in the same area. |
Hey guys, any updates on this PR? We use this patch in production for month already with no issues. |
Ok, well, it looks OK to me, and since the only available feedback is positive, merging. Thanks for the contribution, sorry for the delay! |
Thank you! 👍 |
Awesome ! Thanks @hydiak 🍻 |
@carljm when will there be a patch version released to include this? |
@digitaljhelms i will publish 3.0 later this week. |
Inspired by
#749
#643
Problem
If you include big amount of templates(~200) then precompiled template falls with error:
RangeError: Maximum call stack size exceeded
The problem is large amount of callbacks in compiled code.
It looks like this:
So i wrote a test to reproduce this bug (look at prev. commit):
Solution
Solution is to use waterfall pattern (like async-waterfall) in compiler to decrease amount of call stack size.
It runs the tasks array of functions in series, each passing their results to the next in the array.
Each task runs asynchronously even if it sync. That trick are made by calling each task in setTimout() or setImmediate().
The negative side of of this approach is its extremely low performance. Depends on browser, the function will be called in ~10 ms. Read more about it
So i decide to use sync version of waterfall https://www.npmjs.com/package/a-sync-waterfall
This version of waterfall runs tasks synchronously if it possible, otherwise asynchronously.
And you can pass forceAsync param to run all task asynchronously.
The result looks good to me. Tests are passing, my template with many includes works too.