Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@
"debug": "^4.3.4",
"eventemitter3": "^4.0.7",
"exit-hook": "^2.2.1",
"nanotimer": "^0.3.15",
"p-lazy": "^3.1.0",
"p-queue": "^6.6.2",
"threadedclass": "^1.2.1",
Expand Down
36 changes: 0 additions & 36 deletions src/@types/nanotimer.d.ts

This file was deleted.

65 changes: 38 additions & 27 deletions src/lib/atemSocketChild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* Note: this file wants as few imports as possible, as it gets loaded in a worker-thread and may require its own webpack bundle
*/
import { createSocket, Socket, RemoteInfo } from 'dgram'
import * as NanoTimer from 'nanotimer'
import { performance } from 'perf_hooks'

const IN_FLIGHT_TIMEOUT = 60 // ms
Expand Down Expand Up @@ -47,7 +46,7 @@ export class AtemSocketChild {

private _connectionState = ConnectionState.Closed
private _reconnectTimer: NodeJS.Timer | undefined
private _retransmitTimer: NodeJS.Timer | undefined
private _retransmitTimer: NodeJS.Timeout | undefined

private _nextSendPacketId = 1
private _sessionId = 0
Expand All @@ -59,8 +58,7 @@ export class AtemSocketChild {
private _lastReceivedAt: number = performance.now()
private _lastReceivedPacketId = 0
private _inFlight: InFlightPacket[] = []
private readonly _ackTimer = new NanoTimer()
private _ackTimerRunning = false
private _ackTimer: NodeJS.Timeout | undefined
private _receivedWithoutAck = 0

private readonly onDisconnect: () => Promise<void>
Expand Down Expand Up @@ -100,14 +98,6 @@ export class AtemSocketChild {
})
}, CONNECTION_RETRY_INTERVAL)
}
// Check for retransmits every 10 milliseconds
if (!this._retransmitTimer) {
this._retransmitTimer = setInterval(() => {
this._checkForRetransmit().catch((e) => {
this.log(`Failed to retransmit: ${e?.message ?? e}`)
})
}, RETRANSMIT_INTERVAL)
}
}

public async connect(address: string, port: number): Promise<void> {
Expand All @@ -128,7 +118,7 @@ export class AtemSocketChild {

private _clearTimers() {
if (this._retransmitTimer) {
clearInterval(this._retransmitTimer)
clearTimeout(this._retransmitTimer)
this._retransmitTimer = undefined
}
if (this._reconnectTimer) {
Expand Down Expand Up @@ -199,6 +189,7 @@ export class AtemSocketChild {
payload: buffer,
resent: 0,
})
this._triggerRetransmitTimer()
}

private _recreateSocket(): Socket {
Expand Down Expand Up @@ -307,6 +298,8 @@ export class AtemSocketChild {
return true
}
})
this._triggerRetransmitTimer()

ps.push(this.onCommandsAcknowledged(ackedCommands))
// this.log(`${Date.now()} Got ack ${ackPacketId} Remaining=${this._inFlight.length}`)
}
Expand All @@ -326,21 +319,19 @@ export class AtemSocketChild {
this._receivedWithoutAck++
if (this._receivedWithoutAck >= MAX_PACKET_PER_ACK) {
this._receivedWithoutAck = 0
this._ackTimerRunning = false
this._ackTimer.clearTimeout()

if (this._ackTimer) {
clearTimeout(this._ackTimer)
delete this._ackTimer
}

this._sendAck(this._lastReceivedPacketId)
} else if (!this._ackTimerRunning) {
this._ackTimerRunning = true
// timeout for 5 ms (syntax for nanotimer says m)
this._ackTimer.setTimeout(
() => {
this._receivedWithoutAck = 0
this._ackTimerRunning = false
this._sendAck(this._lastReceivedPacketId)
},
[],
'5m'
)
} else if (!this._ackTimer) {
this._ackTimer = setTimeout(() => {
delete this._ackTimer
this._receivedWithoutAck = 0
this._sendAck(this._lastReceivedPacketId)
}, 5)
}
}

Expand Down Expand Up @@ -382,8 +373,28 @@ export class AtemSocketChild {
}
}

private _triggerRetransmitTimer(): void {
if (!this._inFlight.length && this._retransmitTimer) {
clearTimeout(this._retransmitTimer)
delete this._retransmitTimer
return
}

if (!this._retransmitTimer) {
this._retransmitTimer = setTimeout(() => {
delete this._retransmitTimer
this._checkForRetransmit().catch((e) => {
this.log(`Failed to retransmit: ${e?.message ?? e}`)
})
}, RETRANSMIT_INTERVAL)
}
}

private async _checkForRetransmit(): Promise<void> {
if (!this._inFlight.length) return

this._triggerRetransmitTimer()

const now = performance.now()
for (const sentPacket of this._inFlight) {
if (sentPacket.lastSent + IN_FLIGHT_TIMEOUT < now) {
Expand Down
8 changes: 0 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,6 @@ __metadata:
exit-hook: ^2.2.1
jest: ^29.5.0
jest-extended: ^3.2.4
nanotimer: ^0.3.15
object-path: ^0.11.8
open-cli: ^7.2.0
p-lazy: ^3.1.0
Expand Down Expand Up @@ -4540,13 +4539,6 @@ __metadata:
languageName: node
linkType: hard

"nanotimer@npm:^0.3.15":
version: 0.3.15
resolution: "nanotimer@npm:0.3.15"
checksum: 6b6d686fe6e080c774b0f905ab687acc7a017e19f74882c1b069a1548f8b58f788c9888429d416210d6aecd40d0e100610a96da12c4eb52752eee2722f99f922
languageName: node
linkType: hard

"natural-compare-lite@npm:^1.4.0":
version: 1.4.0
resolution: "natural-compare-lite@npm:1.4.0"
Expand Down