From d003566efc53cc00ac9e6e4198aef05212bc448d Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Mon, 6 Jul 2020 23:46:54 +1000 Subject: [PATCH 01/12] Add smarter networking packet rate control --- .../web_socket_proxy_nuclearnet_client.ts | 12 ++-- .../web_socket_proxy_nuclearnet_server.ts | 69 +++++++++++++------ 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts b/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts index ded36621..16bf93ca 100644 --- a/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts +++ b/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts @@ -5,6 +5,8 @@ import { NUClearNetPacket } from 'nuclearnet.js' import { NUClearPacketListener } from '../../shared/nuclearnet/nuclearnet_client' import { NUClearEventListener } from '../../shared/nuclearnet/nuclearnet_client' import { NUClearNetClient } from '../../shared/nuclearnet/nuclearnet_client' +import { Clock } from '../../shared/time/clock' +import { BrowserSystemClock } from '../time/browser_clock' import { WebWorkerWebSocketClient } from './webworker_web_socket_client' import { WebSocketClient } from './web_socket_client' @@ -24,7 +26,7 @@ export class WebSocketProxyNUClearNetClient implements NUClearNetClient { private leaveListeners: Set private packetListeners: Map> - constructor(private socket: WebSocketClient) { + constructor(private socket: WebSocketClient, private readonly clock: Clock) { this.nextRequestToken = 0 this.joinListeners = new Set() this.leaveListeners = new Set() @@ -38,6 +40,7 @@ export class WebSocketProxyNUClearNetClient implements NUClearNetClient { upgrade: false, transports: ['websocket'], } as any), + BrowserSystemClock, ) } @@ -85,11 +88,10 @@ export class WebSocketProxyNUClearNetClient implements NUClearNetClient { */ const requestToken = String(this.nextRequestToken++) this.socket.send('listen', event, requestToken) - const listener = (packet: NUClearNetPacket, ack?: () => void) => { + const listener = (packet: NUClearNetPacket, ack?: (processingTime: number) => void) => { + const start = this.clock.performanceNow() cb(packet) - if (ack) { - ack() - } + ack?.(this.clock.performanceNow() - start) } this.socket.on(event, listener) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index a920ac45..ca0feaa8 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -158,11 +158,15 @@ class WebSocketServerClient { } } -class PacketProcessor { - private outgoingPackets: number = 0 +type NetStats = { + active: number + latency: number + processingTime: number +} - // The maximum number of packets to send before receiving acknowledgements. - private readonly outgoingLimit: number +class PacketProcessor { + private readonly netstatsByEvent = new Map() + private readonly lastSentByEvent = new Map() // The number of seconds before giving up on an acknowledge private readonly timeout: number @@ -171,9 +175,8 @@ class PacketProcessor { private socket: WebSocket, private clock: Clock, private queue: LruPriorityQueue, - { outgoingLimit, timeout }: { outgoingLimit: number; timeout: number }, + { timeout }: { timeout: number }, ) { - this.outgoingLimit = outgoingLimit this.timeout = timeout this.queue = queue } @@ -183,7 +186,7 @@ class PacketProcessor { socket, NodeSystemClock, new LruPriorityQueue({ capacityPerKey: 2 }), - { outgoingLimit: 10, timeout: 5 }, + { timeout: 5 }, ) } @@ -200,22 +203,48 @@ class PacketProcessor { } private maybeSendNextPacket() { - if (this.outgoingPackets < this.outgoingLimit) { - const next = this.queue.pop() - if (next) { - const { event, packet } = next - let isDone = false - const done = () => { - if (!isDone) { - this.outgoingPackets-- - isDone = true - this.maybeSendNextPacket() + const next = this.queue.pop() + if (next && this.canSendEvent(next.event)) { + const { event, packet } = next + let isDone = false + const stats = this.getStatsForEvent(event) + stats.active++ + const start = this.clock.performanceNow() + const done = (processingTime?: number) => { + if (!isDone) { + // Update our performance tracking information + stats.active -= 1 + if (processingTime != null) { + // Calculate network latency + const latency = this.clock.performanceNow() - start + const n = stats.active + stats.latency = (stats.latency * n + latency) / (n + 1) + stats.processingTime = (stats.processingTime * n + processingTime) / (n + 1) } + isDone = true + this.maybeSendNextPacket() } - this.outgoingPackets++ - this.socket.volatileSend(event, packet, done) - this.clock.setTimeout(done, this.timeout) } + this.socket.volatileSend(event, packet, done) + this.lastSentByEvent.set(event, this.clock.performanceNow()) + this.clock.setTimeout(done, this.timeout) + } + } + + private canSendEvent(event: string): boolean { + const stats = this.getStatsForEvent(event) + const maxRate = stats.processingTime / stats.latency + const lastSent = this.lastSentByEvent.get(event) ?? 0 + const timeSince = this.clock.performanceNow() - lastSent + return timeSince >= maxRate + } + + private getStatsForEvent(event: string): NetStats { + let stats = this.netstatsByEvent.get(event) + if (!stats) { + stats = { active: 0, latency: 1, processingTime: 0.1 } + this.netstatsByEvent.set(event, stats) } + return stats } } From 4d674fed096e728c37e524ca4e454b74d9819c1a Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Mon, 6 Jul 2020 23:49:52 +1000 Subject: [PATCH 02/12] . --- .../tests/web_socket_proxy_nuclearnet_client.tests.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/nuclearnet/tests/web_socket_proxy_nuclearnet_client.tests.ts b/src/client/nuclearnet/tests/web_socket_proxy_nuclearnet_client.tests.ts index a8615ffd..0f8553e3 100644 --- a/src/client/nuclearnet/tests/web_socket_proxy_nuclearnet_client.tests.ts +++ b/src/client/nuclearnet/tests/web_socket_proxy_nuclearnet_client.tests.ts @@ -1,4 +1,5 @@ import { createMockInstance } from '../../../shared/base/testing/create_mock_instance' +import { FakeClock } from '../../../shared/time/fake_clock' import { DirectWebSocketClient } from '../direct_web_socket_client' import { WebSocketProxyNUClearNetClient } from '../web_socket_proxy_nuclearnet_client' import Mocked = jest.Mocked @@ -9,7 +10,7 @@ describe('WebSocketProxyNUClearNetClient', () => { beforeEach(() => { mockWebSocket = createMockInstance(DirectWebSocketClient) - client = new WebSocketProxyNUClearNetClient(mockWebSocket) + client = new WebSocketProxyNUClearNetClient(mockWebSocket, FakeClock.of()) }) it('forwards connect calls to socket', () => { From 776038b07aff5f150cff49a0ed6ecba50894add9 Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Tue, 7 Jul 2020 09:02:22 +1000 Subject: [PATCH 03/12] . --- .../web_socket_proxy_nuclearnet_server.ts | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index ca0feaa8..4da3194f 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -162,11 +162,11 @@ type NetStats = { active: number latency: number processingTime: number + lastSent: number } class PacketProcessor { private readonly netstatsByEvent = new Map() - private readonly lastSentByEvent = new Map() // The number of seconds before giving up on an acknowledge private readonly timeout: number @@ -204,45 +204,49 @@ class PacketProcessor { private maybeSendNextPacket() { const next = this.queue.pop() - if (next && this.canSendEvent(next.event)) { + if (next) { const { event, packet } = next - let isDone = false - const stats = this.getStatsForEvent(event) - stats.active++ - const start = this.clock.performanceNow() - const done = (processingTime?: number) => { - if (!isDone) { - // Update our performance tracking information - stats.active -= 1 - if (processingTime != null) { - // Calculate network latency - const latency = this.clock.performanceNow() - start - const n = stats.active - stats.latency = (stats.latency * n + latency) / (n + 1) - stats.processingTime = (stats.processingTime * n + processingTime) / (n + 1) + const key = `${event}:${packet.peer.name}:${packet.peer.address}:${packet.peer.port}` + if (this.canSendEvent(key)) { + const { event, packet } = next + let isDone = false + const stats = this.getStatsForEvent(key) + stats.active++ + const start = this.clock.performanceNow() + const done = (processingTime?: number) => { + if (!isDone) { + // Update our performance tracking information + stats.active -= 1 + if (processingTime != null) { + // Calculate network latency + const latency = this.clock.performanceNow() - start + const n = stats.active + stats.latency = (stats.latency * n + latency) / (n + 1) + stats.processingTime = (stats.processingTime * n + processingTime) / (n + 1) + } + isDone = true + this.maybeSendNextPacket() } - isDone = true - this.maybeSendNextPacket() } + // this.socket.volatileSend(event, packet, done) + this.socket.send(event, packet, done) + stats.lastSent = this.clock.performanceNow() + this.clock.setTimeout(done, this.timeout) } - this.socket.volatileSend(event, packet, done) - this.lastSentByEvent.set(event, this.clock.performanceNow()) - this.clock.setTimeout(done, this.timeout) } } private canSendEvent(event: string): boolean { const stats = this.getStatsForEvent(event) const maxRate = stats.processingTime / stats.latency - const lastSent = this.lastSentByEvent.get(event) ?? 0 - const timeSince = this.clock.performanceNow() - lastSent + const timeSince = this.clock.performanceNow() - stats.lastSent return timeSince >= maxRate } private getStatsForEvent(event: string): NetStats { let stats = this.netstatsByEvent.get(event) if (!stats) { - stats = { active: 0, latency: 1, processingTime: 0.1 } + stats = { active: 0, latency: 1, processingTime: 0.1, lastSent: 0 } this.netstatsByEvent.set(event, stats) } return stats From 15935f777602776381fe99c84b4c5f190301019d Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Tue, 7 Jul 2020 09:08:51 +1000 Subject: [PATCH 04/12] . --- .../nuclearnet/web_socket_proxy_nuclearnet_server.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index 4da3194f..67ffdedb 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -160,7 +160,6 @@ class WebSocketServerClient { type NetStats = { active: number - latency: number processingTime: number lastSent: number } @@ -212,23 +211,18 @@ class PacketProcessor { let isDone = false const stats = this.getStatsForEvent(key) stats.active++ - const start = this.clock.performanceNow() const done = (processingTime?: number) => { if (!isDone) { // Update our performance tracking information stats.active -= 1 if (processingTime != null) { - // Calculate network latency - const latency = this.clock.performanceNow() - start const n = stats.active - stats.latency = (stats.latency * n + latency) / (n + 1) stats.processingTime = (stats.processingTime * n + processingTime) / (n + 1) } isDone = true this.maybeSendNextPacket() } } - // this.socket.volatileSend(event, packet, done) this.socket.send(event, packet, done) stats.lastSent = this.clock.performanceNow() this.clock.setTimeout(done, this.timeout) @@ -238,15 +232,14 @@ class PacketProcessor { private canSendEvent(event: string): boolean { const stats = this.getStatsForEvent(event) - const maxRate = stats.processingTime / stats.latency const timeSince = this.clock.performanceNow() - stats.lastSent - return timeSince >= maxRate + return timeSince >= stats.processingTime } private getStatsForEvent(event: string): NetStats { let stats = this.netstatsByEvent.get(event) if (!stats) { - stats = { active: 0, latency: 1, processingTime: 0.1, lastSent: 0 } + stats = { active: 0, processingTime: 0.1, lastSent: 0 } this.netstatsByEvent.set(event, stats) } return stats From 0d8355f32120e73451ecf34f78ce390baaf10496 Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Tue, 7 Jul 2020 09:39:09 +1000 Subject: [PATCH 05/12] . --- src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index 67ffdedb..532fab77 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -216,7 +216,8 @@ class PacketProcessor { // Update our performance tracking information stats.active -= 1 if (processingTime != null) { - const n = stats.active + const n = 10 + // https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average stats.processingTime = (stats.processingTime * n + processingTime) / (n + 1) } isDone = true From 67a60d67b50fcf789f93346d7bf7d7e663e55391 Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Tue, 7 Jul 2020 09:40:29 +1000 Subject: [PATCH 06/12] . --- src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index 532fab77..c827b386 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -216,8 +216,8 @@ class PacketProcessor { // Update our performance tracking information stats.active -= 1 if (processingTime != null) { + // https://en.wikipedia.org/wiki/Exponential_smoothing const n = 10 - // https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average stats.processingTime = (stats.processingTime * n + processingTime) / (n + 1) } isDone = true From 2e94b9c71106fdb643a5853192d020fe41b6a5cd Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Sat, 18 Jul 2020 19:09:16 +1000 Subject: [PATCH 07/12] . --- .../web_socket_proxy_nuclearnet_client.ts | 2 + .../web_socket_proxy_nuclearnet_server.ts | 42 +++++++++++++++---- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts b/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts index 16bf93ca..b05c68d6 100644 --- a/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts +++ b/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts @@ -91,7 +91,9 @@ export class WebSocketProxyNUClearNetClient implements NUClearNetClient { const listener = (packet: NUClearNetPacket, ack?: (processingTime: number) => void) => { const start = this.clock.performanceNow() cb(packet) + // setTimeout(() => { ack?.(this.clock.performanceNow() - start) + // }, (packet.payload.length / 512) * 1000) } this.socket.on(event, listener) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index c827b386..967160b9 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -159,13 +159,26 @@ class WebSocketServerClient { } type NetStats = { + // The total number of packets that are out on the wire. active: number processingTime: number + // The total number of payload bytes sent to the client over the lifetime of the connection. + bytesSent: number + // The total number of payload bytes acknowledged from the client over the lifetime of the connection. + bytesAcked: number + // The timestamp of when the last packet was sent. lastSent: number } class PacketProcessor { private readonly netstatsByEvent = new Map() + private readonly stats: NetStats = { + active: 0, + bytesSent: 0, + bytesAcked: 0, + processingTime: 0.1, + lastSent: 0, + } // The number of seconds before giving up on an acknowledge private readonly timeout: number @@ -204,17 +217,20 @@ class PacketProcessor { private maybeSendNextPacket() { const next = this.queue.pop() if (next) { - const { event, packet } = next - const key = `${event}:${packet.peer.name}:${packet.peer.address}:${packet.peer.port}` - if (this.canSendEvent(key)) { + // const { event, packet } = next + // const key = `${event}:${packet.peer.name}:${packet.peer.address}:${packet.peer.port}` + if (this.canSendEvent()) { const { event, packet } = next let isDone = false - const stats = this.getStatsForEvent(key) + // const stats = this.getStatsForEvent(key) + const stats = this.stats stats.active++ + stats.bytesSent += packet.payload.length const done = (processingTime?: number) => { if (!isDone) { // Update our performance tracking information stats.active -= 1 + stats.bytesAcked += packet.payload.length if (processingTime != null) { // https://en.wikipedia.org/wiki/Exponential_smoothing const n = 10 @@ -231,16 +247,24 @@ class PacketProcessor { } } - private canSendEvent(event: string): boolean { - const stats = this.getStatsForEvent(event) - const timeSince = this.clock.performanceNow() - stats.lastSent - return timeSince >= stats.processingTime + private canSendEvent(): boolean { + // const stats = this.getStatsForEvent(event) + const stats = this.stats + // const timeSince = this.clock.performanceNow() - stats.lastSent + // const canProcess = timeSince >= stats.processingTime + + const bytesAhead = stats.bytesSent - stats.bytesAcked + const aheadLimit = 1024 * 10 + const aheadRatio = Math.min(1, bytesAhead / aheadLimit) + // console.log(bytesAhead, 'ratio', aheadRatio) + + return aheadRatio < Math.random() } private getStatsForEvent(event: string): NetStats { let stats = this.netstatsByEvent.get(event) if (!stats) { - stats = { active: 0, processingTime: 0.1, lastSent: 0 } + stats = { active: 0, bytesSent: 0, bytesAcked: 0, processingTime: 0.1, lastSent: 0 } this.netstatsByEvent.set(event, stats) } return stats From 12f641dcbda1da289cbd2e69364350797f7b82df Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Sat, 18 Jul 2020 19:18:54 +1000 Subject: [PATCH 08/12] . --- src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index 967160b9..8305c8e8 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -254,7 +254,7 @@ class PacketProcessor { // const canProcess = timeSince >= stats.processingTime const bytesAhead = stats.bytesSent - stats.bytesAcked - const aheadLimit = 1024 * 10 + const aheadLimit = 1024 * 1024 * 10 const aheadRatio = Math.min(1, bytesAhead / aheadLimit) // console.log(bytesAhead, 'ratio', aheadRatio) From 9b9523e25c93bbeff8f6859a8dc2ea3b84905709 Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Sat, 18 Jul 2020 19:44:44 +1000 Subject: [PATCH 09/12] . --- .../web_socket_proxy_nuclearnet_server.ts | 45 +++++++------------ 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index 8305c8e8..9f1c066e 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -217,56 +217,45 @@ class PacketProcessor { private maybeSendNextPacket() { const next = this.queue.pop() if (next) { - // const { event, packet } = next - // const key = `${event}:${packet.peer.name}:${packet.peer.address}:${packet.peer.port}` if (this.canSendEvent()) { const { event, packet } = next let isDone = false - // const stats = this.getStatsForEvent(key) - const stats = this.stats - stats.active++ - stats.bytesSent += packet.payload.length + this.stats.active++ + this.stats.bytesSent += packet.payload.length const done = (processingTime?: number) => { if (!isDone) { // Update our performance tracking information - stats.active -= 1 - stats.bytesAcked += packet.payload.length + this.stats.active -= 1 + this.stats.bytesAcked += packet.payload.length if (processingTime != null) { // https://en.wikipedia.org/wiki/Exponential_smoothing const n = 10 - stats.processingTime = (stats.processingTime * n + processingTime) / (n + 1) + this.stats.processingTime = (this.stats.processingTime * n + processingTime) / (n + 1) } isDone = true this.maybeSendNextPacket() } } this.socket.send(event, packet, done) - stats.lastSent = this.clock.performanceNow() + this.stats.lastSent = this.clock.performanceNow() this.clock.setTimeout(done, this.timeout) } } } private canSendEvent(): boolean { - // const stats = this.getStatsForEvent(event) - const stats = this.stats - // const timeSince = this.clock.performanceNow() - stats.lastSent - // const canProcess = timeSince >= stats.processingTime - - const bytesAhead = stats.bytesSent - stats.bytesAcked - const aheadLimit = 1024 * 1024 * 10 - const aheadRatio = Math.min(1, bytesAhead / aheadLimit) - // console.log(bytesAhead, 'ratio', aheadRatio) - + const bytesBehind = this.stats.bytesSent - this.stats.bytesAcked + const bytesLow = 1024 * 1024 + const bytesHigh = 1024 * 1024 * 10 + const aheadRatio = lerp(bytesBehind, bytesLow, bytesHigh) return aheadRatio < Math.random() } +} - private getStatsForEvent(event: string): NetStats { - let stats = this.netstatsByEvent.get(event) - if (!stats) { - stats = { active: 0, bytesSent: 0, bytesAcked: 0, processingTime: 0.1, lastSent: 0 } - this.netstatsByEvent.set(event, stats) - } - return stats - } +function lerp(x: number, min: number, max: number): number { + return clamp((x - min) / (max - min), 0, 1) +} + +function clamp(x: number, min: number, max: number) { + return Math.min(Math.max(x, min), max) } From a20ef63adcddc91a92c6b45fb2d9d36dbcf7c71b Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Sat, 18 Jul 2020 19:45:13 +1000 Subject: [PATCH 10/12] . --- .../nuclearnet/web_socket_proxy_nuclearnet_client.ts | 7 ++----- .../nuclearnet/web_socket_proxy_nuclearnet_server.ts | 10 +--------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts b/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts index b05c68d6..bb4029a0 100644 --- a/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts +++ b/src/client/nuclearnet/web_socket_proxy_nuclearnet_client.ts @@ -88,12 +88,9 @@ export class WebSocketProxyNUClearNetClient implements NUClearNetClient { */ const requestToken = String(this.nextRequestToken++) this.socket.send('listen', event, requestToken) - const listener = (packet: NUClearNetPacket, ack?: (processingTime: number) => void) => { - const start = this.clock.performanceNow() + const listener = (packet: NUClearNetPacket, ack?: () => void) => { cb(packet) - // setTimeout(() => { - ack?.(this.clock.performanceNow() - start) - // }, (packet.payload.length / 512) * 1000) + ack?.() } this.socket.on(event, listener) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index 9f1c066e..64c69c1a 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -161,7 +161,6 @@ class WebSocketServerClient { type NetStats = { // The total number of packets that are out on the wire. active: number - processingTime: number // The total number of payload bytes sent to the client over the lifetime of the connection. bytesSent: number // The total number of payload bytes acknowledged from the client over the lifetime of the connection. @@ -171,12 +170,10 @@ type NetStats = { } class PacketProcessor { - private readonly netstatsByEvent = new Map() private readonly stats: NetStats = { active: 0, bytesSent: 0, bytesAcked: 0, - processingTime: 0.1, lastSent: 0, } @@ -222,16 +219,11 @@ class PacketProcessor { let isDone = false this.stats.active++ this.stats.bytesSent += packet.payload.length - const done = (processingTime?: number) => { + const done = () => { if (!isDone) { // Update our performance tracking information this.stats.active -= 1 this.stats.bytesAcked += packet.payload.length - if (processingTime != null) { - // https://en.wikipedia.org/wiki/Exponential_smoothing - const n = 10 - this.stats.processingTime = (this.stats.processingTime * n + processingTime) / (n + 1) - } isDone = true this.maybeSendNextPacket() } From 68025476e145b31d4f4650e0d67fb03bc74993bd Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Sat, 18 Jul 2020 19:47:42 +1000 Subject: [PATCH 11/12] . --- src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index 64c69c1a..247ceb11 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -239,8 +239,8 @@ class PacketProcessor { const bytesBehind = this.stats.bytesSent - this.stats.bytesAcked const bytesLow = 1024 * 1024 const bytesHigh = 1024 * 1024 * 10 - const aheadRatio = lerp(bytesBehind, bytesLow, bytesHigh) - return aheadRatio < Math.random() + const behindRatio = lerp(bytesBehind, bytesLow, bytesHigh) + return behindRatio < Math.random() } } From 7cd4788145798dd2c4fad77f7335a16cd343eabc Mon Sep 17 00:00:00 2001 From: Brendan Annable Date: Sat, 18 Jul 2020 20:32:02 +1000 Subject: [PATCH 12/12] . --- src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts index 247ceb11..ec62e046 100644 --- a/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts +++ b/src/server/nuclearnet/web_socket_proxy_nuclearnet_server.ts @@ -228,7 +228,7 @@ class PacketProcessor { this.maybeSendNextPacket() } } - this.socket.send(event, packet, done) + this.socket.volatileSend(event, packet, done) this.stats.lastSent = this.clock.performanceNow() this.clock.setTimeout(done, this.timeout) }