From dad588fe67699773b68739a141a60592f3420138 Mon Sep 17 00:00:00 2001 From: Trent Willis Date: Sun, 26 Jan 2020 20:05:18 -0800 Subject: [PATCH] Improve performance for large messages across many chunks (#130) --- lib/eventsource.js | 11 +++++++++-- test/eventsource_test.js | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/eventsource.js b/lib/eventsource.js index f3f593e..025941c 100644 --- a/lib/eventsource.js +++ b/lib/eventsource.js @@ -181,6 +181,8 @@ function EventSource (url, eventSourceInitDict) { // Source/WebCore/page/EventSource.cpp var isFirst = true var buf + var startingPos = 0 + var startingFieldLength = -1 res.on('data', function (chunk) { buf = buf ? Buffer.concat([buf, chunk]) : chunk if (isFirst && hasBom(buf)) { @@ -200,10 +202,10 @@ function EventSource (url, eventSourceInitDict) { } var lineLength = -1 - var fieldLength = -1 + var fieldLength = startingFieldLength var c - for (var i = pos; lineLength < 0 && i < length; ++i) { + for (var i = startingPos; lineLength < 0 && i < length; ++i) { c = buf[i] if (c === colon) { if (fieldLength < 0) { @@ -218,7 +220,12 @@ function EventSource (url, eventSourceInitDict) { } if (lineLength < 0) { + startingPos = length - pos + startingFieldLength = fieldLength break + } else { + startingPos = 0 + startingFieldLength = -1 } parseEventStreamLine(buf, pos, fieldLength, lineLength) diff --git a/test/eventsource_test.js b/test/eventsource_test.js index 9c430d9..3ae6692 100644 --- a/test/eventsource_test.js +++ b/test/eventsource_test.js @@ -467,6 +467,26 @@ describe('Parser', function () { } }) }) + + it('parses a relatively huge message across many chunks efficiently', function (done) { + this.timeout(1000) + + createServer(function (err, server) { + if (err) return done(err) + + var longMessageContent = new Array(100000).join('a') + var longMessage = 'data: ' + longMessageContent + '\n\n' + var longMessageChunks = longMessage.match(/[\s\S]{1,10}/g) // Split the message into chunks of 10 characters + server.on('request', writeEvents(longMessageChunks)) + + var es = new EventSource(server.url) + + es.onmessage = function (m) { + assert.equal(longMessageContent, m.data) + server.close(done) + } + }) + }) }) describe('HTTP Request', function () {