22
33const DEFAULT_SPIN_RATE_HZ = 200 ;
44const events = require ( 'events' ) ;
5- const LoggingManager = require ( '../lib/Logging.js' ) ;
5+ const LoggingManager = require ( '../../ lib/Logging.js' ) ;
66const log = LoggingManager . getLogger ( 'ros.spinner' ) ;
77
8+ const ClientQueue = require ( './ClientQueue.js' ) ;
9+
810const PING_OP = 'ping' ;
911const DELETE_OP = 'delete' ;
10-
11- /**
12- * @class ClientQueue
13- * Queue of messages to handle for an individual client (subscriber or publisher)
14- */
15- class ClientQueue {
16- constructor ( client , queueSize , throttleMs ) {
17- if ( queueSize < 1 ) {
18- throw new Error ( `Unable to create client message queue with size ${ queueSize } - minimum is 1` ) ;
19- }
20-
21- this . _client = client ;
22-
23- this . _queue = [ ] ;
24- this . _queueSize = queueSize ;
25-
26- this . throttleMs = throttleMs ;
27- this . _handleTime = null ;
28- }
29-
30- push ( item ) {
31- this . _queue . push ( item ) ;
32- if ( this . length > this . _queueSize ) {
33- this . _queue . shift ( ) ;
34- }
35- }
36-
37- get length ( ) {
38- return this . _queue . length ;
39- }
40-
41- handleClientMessages ( time ) {
42- if ( this . _handleTime === null || time - this . _handleTime >= this . throttleMs ) {
43- this . _handleTime = time ;
44- this . _client . _handleMsgQueue ( this . _queue ) ;
45- this . _queue = [ ] ;
46- return true ;
47- }
48- // else
49- return false ;
50- }
51- }
12+ const ADD_OP = 'add' ;
5213
5314/**
5415 * @class GlobalSpinner
@@ -66,15 +27,16 @@ class ClientQueue {
6627 * ping and disconnect operations are replayed in order.
6728 */
6829class GlobalSpinner extends events {
69- constructor ( spinRate = DEFAULT_SPIN_RATE_HZ , emit = false ) {
30+ constructor ( { spinRate= null , emit= false } = { } ) {
7031 super ( ) ;
7132
72- if ( typeof spinRate !== 'number' ) {
73- spinRate = DEFAULT_SPIN_RATE_HZ ;
33+ if ( typeof spinRate === 'number' ) {
34+ this . _spinTime = 1 / spinRate ;
35+ }
36+ else {
37+ this . _spinTime = 0 ;
7438 }
7539
76- this . _spinTime = 1 / spinRate ;
77- this . _expectedSpinExpire = null ;
7840 this . _spinTimer = null ;
7941
8042 this . _clientCallQueue = [ ] ;
@@ -92,8 +54,21 @@ class GlobalSpinner extends events {
9254 this . _emit = emit ;
9355 }
9456
57+ clear ( ) {
58+ clearTimeout ( this . _spinTimer ) ;
59+ this . _queueLocked = false ;
60+ this . _clientQueueMap . forEach ( ( clientQueue ) => {
61+ clientQueue . destroy ( ) ;
62+ } ) ;
63+ this . _clientQueueMap . clear ( ) ;
64+ this . _clientCallQueue = [ ] ;
65+ }
66+
9567 addClient ( client , clientId , queueSize , throttleMs ) {
96- if ( queueSize > 0 ) {
68+ if ( this . _queueLocked ) {
69+ this . _lockedOpCache . push ( { op : ADD_OP , client, clientId, queueSize, throttleMs} ) ;
70+ }
71+ else if ( queueSize > 0 ) {
9772 this . _clientQueueMap . set ( clientId , new ClientQueue ( client , queueSize , throttleMs ) ) ;
9873 }
9974 }
@@ -147,28 +122,20 @@ class GlobalSpinner extends events {
147122 _handleLockedOpCache ( ) {
148123 const len = this . _lockedOpCache . length ;
149124 for ( let i = 0 ; i < len ; ++ i ) {
150- const { op, clientId, msg} = this . _lockedOpCache [ i ] ;
125+ const { op, clientId, msg, client , queueSize , throttleMs } = this . _lockedOpCache [ i ] ;
151126 if ( op === PING_OP ) {
152127 this . ping ( clientId , msg ) ;
153128 }
154129 else if ( op === DELETE_OP ) {
155130 this . disconnect ( clientId ) ;
156131 }
132+ else if ( op === ADD_OP ) {
133+ this . addClient ( client , clientId , queueSize , throttleMs ) ;
134+ }
157135 }
158136 this . _lockedOpCache = [ ] ;
159137 }
160138
161- _getClientsWithQueuedMessages ( ) {
162- const clients = { } ;
163- this . _clientQueueMap . forEach ( ( value , clientId ) => {
164- const queueSize = value . length ;
165- clients [ clientId ] = queueSize ;
166- if ( queueSize > 0 && this . _clientCallQueue . indexOf ( clientId ) === - 1 ) {
167- throw new Error ( `Client ${ clientId } has ${ value . length } queued messages but is not in call list!` ) ;
168- }
169- } ) ;
170- }
171-
172139 _setTimer ( ) {
173140 if ( this . _spinTimer === null ) {
174141 if ( this . _emit ) {
@@ -180,7 +147,6 @@ class GlobalSpinner extends events {
180147 else {
181148 this . _spinTimer = setTimeout ( this . _handleQueue . bind ( this ) , this . _spinTime ) ;
182149 }
183- this . _expectedSpinExpire = Date . now ( ) + this . _spinTime ;
184150 }
185151 }
186152
@@ -223,4 +189,4 @@ class GlobalSpinner extends events {
223189 }
224190}
225191
226- module . exports = GlobalSpinner ;
192+ module . exports = GlobalSpinner ;
0 commit comments