@@ -14,14 +14,11 @@ import { sendRawPacket } from "../packet";
1414export class Router extends NetworkDevice {
1515 static DEVICE_TEXTURE : Texture ;
1616
17- private processingPackets = false ;
17+ private packetQueue = new PacketQueue ( 1024 ) ;
18+ // Time in ms to process a single byte
19+ private timePerByte = 8 ;
20+ // Number of bytes processed
1821 private processingProgress = 0 ;
19- // Time in ms to process a single packet
20- private timePerPacket = 250 ;
21-
22- private packetQueue : IPv4Packet [ ] = [ ] ;
23- // TODO: we should count this in bytes
24- private maxQueueSize = 5 ;
2522
2623 static getTexture ( ) {
2724 if ( ! Router . DEVICE_TEXTURE ) {
@@ -69,25 +66,21 @@ export class Router extends NetworkDevice {
6966 }
7067
7168 addPacketToQueue ( datagram : IPv4Packet ) {
72- if ( this . packetQueue . length >= this . maxQueueSize ) {
69+ const wasEmpty = this . packetQueue . isEmpty ( ) ;
70+ if ( ! this . packetQueue . enqueue ( datagram ) ) {
7371 console . debug ( "Packet queue full, dropping packet" ) ;
7472 return ;
7573 }
76- this . packetQueue . push ( datagram ) ;
77- // Start packet processor if not already running
78- if ( ! this . processingPackets ) {
79- Ticker . shared . add ( this . processPacket , this ) ;
80- this . processingPackets = true ;
74+ if ( wasEmpty ) {
75+ this . startPacketProcessor ( ) ;
8176 }
8277 }
8378
8479 processPacket ( ticker : Ticker ) {
85- this . processingProgress += ticker . deltaMS ;
86- if ( this . processingProgress < this . timePerPacket ) {
80+ const datagram = this . getPacketsToProcess ( ticker . deltaMS ) ;
81+ if ( ! datagram ) {
8782 return ;
8883 }
89- this . processingProgress -= this . timePerPacket ;
90- const datagram = this . packetQueue . pop ( ) ;
9184 const devices = this . routePacket ( datagram ) ;
9285
9386 if ( ! devices || devices . length === 0 ) {
@@ -104,13 +97,30 @@ export class Router extends NetworkDevice {
10497 sendRawPacket ( this . viewgraph , this . id , newFrame ) ;
10598 }
10699
107- // Stop processing packets if queue is empty
108- if ( this . packetQueue . length === 0 ) {
109- Ticker . shared . remove ( this . processPacket , this ) ;
110- this . processingPackets = false ;
111- this . processingProgress = 0 ;
112- return ;
100+ if ( this . packetQueue . isEmpty ( ) ) {
101+ this . stopPacketProcessor ( ) ;
102+ }
103+ }
104+
105+ startPacketProcessor ( ) {
106+ this . processingProgress = 0 ;
107+ Ticker . shared . add ( this . processPacket , this ) ;
108+ }
109+
110+ stopPacketProcessor ( ) {
111+ this . processingProgress = 0 ;
112+ Ticker . shared . remove ( this . processPacket , this ) ;
113+ }
114+
115+ getPacketsToProcess ( timeMs : number ) : IPv4Packet | null {
116+ this . processingProgress += timeMs ;
117+ const packetLength = this . packetQueue . getHead ( ) ?. totalLength ;
118+ const progressNeeded = this . timePerByte * packetLength ;
119+ if ( this . processingProgress < progressNeeded ) {
120+ return null ;
113121 }
122+ this . processingProgress -= progressNeeded ;
123+ return this . packetQueue . dequeue ( ) ;
114124 }
115125
116126 routePacket ( datagram : IPv4Packet ) : DeviceId [ ] {
@@ -147,3 +157,39 @@ export class Router extends NetworkDevice {
147157 return devices ;
148158 }
149159}
160+
161+ class PacketQueue {
162+ private queue : IPv4Packet [ ] = [ ] ;
163+ private queueSizeBytes = 0 ;
164+ private maxQueueSizeBytes : number ;
165+
166+ constructor ( maxQueueSizeBytes : number ) {
167+ this . maxQueueSizeBytes = maxQueueSizeBytes ;
168+ }
169+
170+ enqueue ( packet : IPv4Packet ) {
171+ if ( this . queueSizeBytes >= this . maxQueueSizeBytes ) {
172+ return false ;
173+ }
174+ this . queue . push ( packet ) ;
175+ this . queueSizeBytes += packet . totalLength ;
176+ return true ;
177+ }
178+
179+ dequeue ( ) : IPv4Packet | undefined {
180+ if ( this . queue . length === 0 ) {
181+ return ;
182+ }
183+ const packet = this . queue . shift ( ) ;
184+ this . queueSizeBytes -= packet . totalLength ;
185+ return packet ;
186+ }
187+
188+ getHead ( ) : IPv4Packet | undefined {
189+ return this . queue [ 0 ] ;
190+ }
191+
192+ isEmpty ( ) : boolean {
193+ return this . queue . length === 0 ;
194+ }
195+ }
0 commit comments