Skip to content

Commit 0e9ceb1

Browse files
authored
Remove handled fragmented messages from the map (#571)
* Remove handled fragmented messages from the map We should remove handled fragmented messages from fragmentedMessages map to free it up. This PR includes this fix. Also, FragmentedClientMessageHandlerTest is enhanced to check the the map's size before and after merging and handling the end fragment. * address review comments
1 parent c7d063a commit 0e9ceb1

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

src/network/ClientConnection.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -242,25 +242,32 @@ export class ClientMessageReader {
242242
/** @internal */
243243
export class FragmentedClientMessageHandler {
244244
private readonly fragmentedMessages = new Map<number, ClientMessage>();
245+
private readonly logger: ILogger;
246+
247+
constructor(logger: ILogger) {
248+
this.logger = logger;
249+
}
245250

246251
handleFragmentedMessage(clientMessage: ClientMessage, callback: Function): void {
247252
const fragmentationFrame = clientMessage.startFrame;
248253
const fragmentationId = clientMessage.getFragmentationId();
249254
clientMessage.dropFragmentationFrame();
250255
if (fragmentationFrame.hasBeginFragmentFlag()) {
251256
this.fragmentedMessages.set(fragmentationId, clientMessage);
252-
} else if (fragmentationFrame.hasEndFragmentFlag()) {
253-
const mergedMessage = this.mergeIntoExistingClientMessage(fragmentationId, clientMessage);
254-
callback(mergedMessage);
255257
} else {
256-
this.mergeIntoExistingClientMessage(fragmentationId, clientMessage);
257-
}
258-
}
258+
const existingMessage = this.fragmentedMessages.get(fragmentationId);
259+
if (existingMessage == null) {
260+
this.logger.debug('FragmentedClientMessageHandler',
261+
'A fragmented message without the begin part is received. Fragmentation id: ' + fragmentationId);
262+
return;
263+
}
259264

260-
private mergeIntoExistingClientMessage(fragmentationId: number, clientMessage: ClientMessage): ClientMessage {
261-
const existingMessage = this.fragmentedMessages.get(fragmentationId);
262-
existingMessage.merge(clientMessage);
263-
return existingMessage;
265+
existingMessage.merge(clientMessage);
266+
if (fragmentationFrame.hasEndFragmentFlag()) {
267+
this.fragmentedMessages.delete(fragmentationId);
268+
callback(existingMessage);
269+
}
270+
}
264271
}
265272
}
266273

@@ -304,7 +311,7 @@ export class ClientConnection {
304311
this.reader = new ClientMessageReader();
305312
this.connectionId = connectionId;
306313
this.logger = this.client.getLoggingService().getLogger();
307-
this.fragmentedMessageHandler = new FragmentedClientMessageHandler();
314+
this.fragmentedMessageHandler = new FragmentedClientMessageHandler(this.logger);
308315
}
309316

310317
/**

test/connection/FragmentedClientMessageHandlerTest.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@ const ClientMessageReader = require('../../lib/network/ClientConnection').Client
2424
const cm = require('../../lib/ClientMessage');
2525
const FixSizedTypesCodec = require('../../lib/codec/builtin/FixSizedTypesCodec').FixSizedTypesCodec;
2626

27-
describe('FragmentedClientMessageHandler', function () {
27+
describe('FragmentedClientMessageHandlerTest', function () {
2828

2929
let reader;
3030
let handler;
3131

3232
beforeEach(() => {
3333
reader = new ClientMessageReader();
34-
handler = new FragmentedClientMessageHandler();
34+
handler = new FragmentedClientMessageHandler({
35+
debug: () => {}
36+
});
3537
});
3638

3739
it('handles fragmented message', function (done) {
@@ -62,15 +64,25 @@ describe('FragmentedClientMessageHandler', function () {
6264

6365
// Should merge with the above message
6466
handler.handleFragmentedMessage(fragment1, () => done(new Error("It should just merge.")));
67+
expect(handler.fragmentedMessages.size).to.equal(1);
6568
compareMessages(fragments[1].startFrame.next, endFrame.next);
6669
endFrame = fragmentedMessage.endFrame;
6770

6871
// Should merge with the above message and run the callback
72+
let isCalled = false;
6973
handler.handleFragmentedMessage(fragment2, () => {
7074
compareMessages(fragments[2].startFrame.next, endFrame.next);
71-
done();
75+
isCalled = true;
7276
});
77+
expect(isCalled).to.be.true;
78+
expect(handler.fragmentedMessages.size).to.equal(0);
79+
80+
// If a message with a missing begin part is received, we should do nothing
81+
handler.handleFragmentedMessage(fragment1, () => done(new Error("It should ignore invalid messages.")))
82+
handler.handleFragmentedMessage(fragment2, () => done(new Error("It should ignore invalid messages.")))
83+
expect(handler.fragmentedMessages.size).to.equal(0);
7384

85+
done();
7486
});
7587

7688
const compareMessages = (frame1, frame2) => {

0 commit comments

Comments
 (0)