mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 15:24:52 +09:00
Merge pull request #1057 from bbassie/fix/bounded-send-buffer
Limit unacknowledged messages buffered for a connection
This commit is contained in:
7 files changed
+124
-11
No files matched your search
@@ -3,8 +3,9 @@ import events from "node:events";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import {
|
||||
TestControlConnector, TestHostConnector, TestControl, url, controlToken,
|
||||
TestControlConnector, TestHostConnector, TestControl, url, controlToken, getControl,
|
||||
} from "./index.js";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { ConnectionClosed, ProtocolError, PolicyViolation, AuthenticationFailed } from "@clusterio/lib";
|
||||
import { slowTest } from "../common.js";
|
||||
|
||||
@@ -92,6 +93,33 @@ describe("Integration of lib/link", function() {
|
||||
await events.once(controlConnector, "connect");
|
||||
});
|
||||
|
||||
it("should start a new session when the send buffer limit is exceeded", async function() {
|
||||
await getControl().send(new lib.ControllerConfigSetFieldRequest("controller.max_send_buffer_size", "0.01"));
|
||||
try {
|
||||
await controlConnector.connect();
|
||||
} finally {
|
||||
await getControl().send(new lib.ControllerConfigSetFieldRequest("controller.max_send_buffer_size", "64"));
|
||||
}
|
||||
|
||||
// Never acknowledge received messages
|
||||
controlConnector._doHeartbeat = function() {
|
||||
this._sendInternal(new lib.MessageHeartbeat());
|
||||
};
|
||||
let invalidated = false;
|
||||
controlConnector.once("invalidate", () => { invalidated = true; });
|
||||
const connected = events.once(controlConnector, "invalidate").then(
|
||||
() => events.once(controlConnector, "connect")
|
||||
);
|
||||
for (let i = 0; i < 100; i++) {
|
||||
if (invalidated) {
|
||||
break;
|
||||
}
|
||||
await control.send(new lib.ControllerConfigGetRequest()).catch(() => {});
|
||||
}
|
||||
assert(invalidated, "session was not invalidated");
|
||||
await connected;
|
||||
});
|
||||
|
||||
it("should properly close connector if close is called during reconnect wait", async function() {
|
||||
await controlConnector.connect();
|
||||
controlConnector._socket.close(ConnectionClosed.Normal, "Test");
|
||||
|
||||
@@ -13,10 +13,11 @@ describe("lib/link/connectors", function() {
|
||||
describe("._dropSendBufferSeq()", function() {
|
||||
beforeEach(function() {
|
||||
testConnector._sendBuffer = [
|
||||
{ seq: 1, type: "test", data: {} },
|
||||
{ seq: 2, type: "test", data: {} },
|
||||
{ seq: 4, type: "test", data: {} },
|
||||
{ seq: 1, text: "a" },
|
||||
{ seq: 2, text: "bb" },
|
||||
{ seq: 4, text: "cccc" },
|
||||
];
|
||||
testConnector._sendBufferSize = 7;
|
||||
});
|
||||
it("should do nothing if passed null", function() {
|
||||
testConnector._dropSendBufferSeq(null);
|
||||
@@ -25,6 +26,7 @@ describe("lib/link/connectors", function() {
|
||||
it("should drop up to sequence", function() {
|
||||
testConnector._dropSendBufferSeq(2);
|
||||
assert.equal(testConnector._sendBuffer.length, 1, "incorrect number of entries dropped");
|
||||
assert.equal(testConnector._sendBufferSize, 4);
|
||||
});
|
||||
it("should ignore holes", function() {
|
||||
testConnector._dropSendBufferSeq(3);
|
||||
@@ -61,6 +63,37 @@ describe("lib/link/connectors", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("send buffer limit", function() {
|
||||
afterEach(function() {
|
||||
testConnector.maxSendBufferSize = 0;
|
||||
testConnector._closing = false;
|
||||
});
|
||||
it("should keep unacknowledged messages under the limit", function() {
|
||||
testConnector._state = "connected";
|
||||
testConnector._sendBuffer = [];
|
||||
testConnector._sendBufferSize = 0;
|
||||
testConnector._socket.closeCalled = false;
|
||||
testConnector.maxSendBufferSize = 1000;
|
||||
testConnector.send(new lib.MessageHeartbeat(1));
|
||||
assert.equal(testConnector._sendBuffer.length, 1);
|
||||
assert(!testConnector._socket.closeCalled, "Close was called on the socket");
|
||||
});
|
||||
it("should clear the buffer and close when the limit is exceeded", function() {
|
||||
testConnector._state = "connected";
|
||||
testConnector._sendBuffer = [];
|
||||
testConnector._sendBufferSize = 0;
|
||||
testConnector._socket.closeCalled = false;
|
||||
testConnector._socket.sentMessages = [];
|
||||
testConnector.maxSendBufferSize = 30;
|
||||
testConnector.send(new lib.MessageHeartbeat(1));
|
||||
testConnector.send(new lib.MessageHeartbeat(2));
|
||||
assert.equal(testConnector._sendBuffer.length, 0);
|
||||
assert.equal(testConnector._sendBufferSize, 0);
|
||||
assert(testConnector._socket.closeCalled, "Close was not called on the socket");
|
||||
assert.equal(testConnector._socket.sentMessages.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe(".close()", function() {
|
||||
it("should call close", function() {
|
||||
testConnector._socket.closeCalled = false;
|
||||
|
||||
Reference in new issue
Block a user