From 097bb2e4e84864f856ccd244aed3bf316daa07ef Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 8 May 2016 18:11:19 -0400 Subject: [PATCH] tweak render stream implementation --- src/server/render-stream.js | 68 ++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/src/server/render-stream.js b/src/server/render-stream.js index ff1ef7bb..6142fd29 100644 --- a/src/server/render-stream.js +++ b/src/server/render-stream.js @@ -1,6 +1,6 @@ import stream from 'stream' -const MAX_STACK_DEPTH = 500 +const MAX_STACK_DEPTH = 1000 /** * Original RenderStream implmentation by Sasha Aickin (@aickin) @@ -12,10 +12,42 @@ export default class RenderStream extends stream.Readable { super() this.buffer = '' this.render = render + this.expectedSize = 0 + + this.write = (text, next) => { + const n = this.expectedSize + this.buffer += text + if (this.buffer.length >= n) { + this.next = next + this.pushBySize(n) + } else { + // continue rendering until we have enough text to call this.push(). + // sometimes do this as process.nextTick to get out of stack overflows. + if (this.stackDepth >= MAX_STACK_DEPTH) { + process.nextTick(next) + } else { + this.stackDepth++ + next() + this.stackDepth-- + } + } + } + + this.end = () => { + // the rendering is finished; we should push out the last of the buffer. + this.done = true + this.push(this.buffer) + } + } + + pushBySize (n) { + const bufferToPush = this.buffer.substring(0, n) + this.buffer = this.buffer.substring(n) + this.push(bufferToPush) } _read (n) { - let bufferToPush + this.expectedSize = n // it's possible that the last chunk added bumped the buffer up to > 2 * n, // which means we will need to go through multiple read calls to drain it // down to < n. @@ -24,41 +56,13 @@ export default class RenderStream extends stream.Readable { return } if (this.buffer.length >= n) { - bufferToPush = this.buffer.substring(0, n) - this.buffer = this.buffer.substring(n) - this.push(bufferToPush) + this.pushBySize(n) return } if (!this.next) { this.stackDepth = 0 // start the rendering chain. - this.render( - // write - (text, next) => { - this.buffer += text - if (this.buffer.length >= n) { - this.next = next - bufferToPush = this.buffer.substring(0, n) - this.buffer = this.buffer.substring(n) - this.push(bufferToPush) - } else { - // continue rendering until we have enough text to call this.push(). - // sometimes do this as process.nextTick to get out of stack overflows. - if (this.stackDepth >= MAX_STACK_DEPTH) { - process.nextTick(next) - } else { - this.stackDepth++ - next() - this.stackDepth-- - } - } - }, - // done - () => { - // the rendering is finished; we should push out the last of the buffer. - this.done = true - this.push(this.buffer) - }) + this.render(this.write, this.end) } else { // continue with the rendering. this.next()