Skip to content
This repository was archived by the owner on Apr 3, 2024. It is now read-only.

Commit a421509

Browse files
authored
feat: add active debuggee support (#1121)
* wip: add timestamps to register call * fix: update the names of the timestamp fields * wip: working on tests; there are issues * wip: restructured and tests are passing * wip: registration complete * feat: add active debuggee support * fix: relax the test constraints for marking active debuggees * address PR feedback
1 parent 42ee4a7 commit a421509

File tree

2 files changed

+239
-86
lines changed

2 files changed

+239
-86
lines changed

src/agent/firebase-controller.ts

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)