@@ -36,6 +36,9 @@ export class FirebaseController implements Controller {
3636 debuggeeId ?: string ;
3737 bpRef ?: firebase . database . Reference ;
3838
39+ markActiveInterval : ReturnType < typeof setInterval > | undefined ;
40+ markActivePeriodMsec : number = 60 * 60 * 1000 ; // 1 hour in ms.
41+
3942 /**
4043 * Connects to the Firebase database.
4144 *
@@ -135,7 +138,10 @@ export class FirebaseController implements Controller {
135138 }
136139
137140 /**
138- * Register to the API (implementation)
141+ * Register to the API (implementation).
142+ *
143+ * Writes an initial record to the database if it is not yet present.
144+ * Otherwise only updates the last active timestamp.
139145 *
140146 * @param {!function(?Error,Object=) } callback
141147 * @private
@@ -168,15 +174,29 @@ export class FirebaseController implements Controller {
168174 this . debuggeeId = `d-${ debuggeeHash . substring ( 0 , 8 ) } ` ;
169175 debuggee . id = this . debuggeeId ;
170176
171- const debuggeeRef = this . db . ref ( `cdbg/debuggees/${ this . debuggeeId } ` ) ;
172- debuggeeRef . set ( debuggee as { } , err => {
173- if ( err ) {
174- callback ( err ) ;
175- } else {
176- const agentId = 'unsupported' ;
177- callback ( null , { debuggee, agentId} ) ;
178- }
179- } ) ;
177+ const agentId = 'unsupported' ;
178+ // Test presence using the registration time. This moves less data.
179+ const presenceRef = this . db . ref (
180+ `cdbg/debuggees/${ this . debuggeeId } /registrationTimeUnixMsec`
181+ ) ;
182+ presenceRef
183+ . get ( )
184+ . then ( presenceSnapshot => {
185+ if ( presenceSnapshot . exists ( ) ) {
186+ return this . markDebuggeeActive ( ) ;
187+ } else {
188+ const ref = this . db . ref ( `cdbg/debuggees/${ this . debuggeeId } ` ) ;
189+ return ref . set ( {
190+ registrationTimeUnixMsec : { '.sv' : 'timestamp' } ,
191+ lastUpdateTimeUnixMsec : { '.sv' : 'timestamp' } ,
192+ ...debuggee ,
193+ } ) ;
194+ }
195+ } )
196+ . then (
197+ ( ) => callback ( null , { debuggee, agentId} ) ,
198+ err => callback ( err )
199+ ) ;
180200 }
181201
182202 /**
@@ -300,6 +320,26 @@ export class FirebaseController implements Controller {
300320 callback ( e , [ ] ) ;
301321 }
302322 ) ;
323+
324+ this . startMarkingDebuggeeActive ( ) ;
325+ }
326+
327+ startMarkingDebuggeeActive ( ) {
328+ debuglog ( `starting to mark every ${ this . markActivePeriodMsec } ms` ) ;
329+ this . markActiveInterval = setInterval ( ( ) => {
330+ this . markDebuggeeActive ( ) ;
331+ } , this . markActivePeriodMsec ) ;
332+ }
333+
334+ /**
335+ * Marks a debuggee as active by prompting the server to update the
336+ * lastUpdateTimeUnixMsec to server time.
337+ */
338+ async markDebuggeeActive ( ) : Promise < void > {
339+ const ref = this . db . ref (
340+ `cdbg/debuggees/${ this . debuggeeId } /lastUpdateTimeUnixMsec`
341+ ) ;
342+ await ref . set ( { '.sv' : 'timestamp' } ) ;
303343 }
304344
305345 stop ( ) : void {
@@ -312,5 +352,9 @@ export class FirebaseController implements Controller {
312352 } catch ( err ) {
313353 debuglog ( `failed to tear down firebase app: ${ err } )` ) ;
314354 }
355+ if ( this . markActiveInterval ) {
356+ clearInterval ( this . markActiveInterval ) ;
357+ this . markActiveInterval = undefined ;
358+ }
315359 }
316360}
0 commit comments