From b26a1c28b6167a5b8db6e5be6c61c2a6cb661b60 Mon Sep 17 00:00:00 2001 From: Alex Kaminskii Date: Fri, 18 Nov 2022 19:43:35 +0100 Subject: [PATCH] fix(tracker):4.1.7:re-send metadata on start, clean session data logic a bit --- tracker/tracker/src/main/app/index.ts | 63 +++++++++++++------------ tracker/tracker/src/main/app/session.ts | 2 +- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/tracker/tracker/src/main/app/index.ts b/tracker/tracker/src/main/app/index.ts index 9c640af29..ce2473ef5 100644 --- a/tracker/tracker/src/main/app/index.ts +++ b/tracker/tracker/src/main/app/index.ts @@ -164,7 +164,7 @@ export default class App { this.worker.onmessage = ({ data }: MessageEvent) => { if (data === 'restart') { this.stop(false) - this.start({ forceNew: true }) // TODO: keep userID & metadata (draw scenarios) + this.start({}, true) } else if (data.type === 'failure') { this.stop(false) this._debug('worker_failed', data.reason) @@ -201,7 +201,6 @@ export default class App { send(message: Message, urgent = false): void { if (this.activityState === ActivityState.NotActive) { - // this.debug.log('SendiTrying to send when not active', message) <- crashing the app return } this.messages.push(message) @@ -370,7 +369,7 @@ export default class App { this.sessionStorage.removeItem(this.options.session_reset_key) } } - private _start(startOpts: StartOptions): Promise { + private _start(startOpts: StartOptions = {}, resetByWorker = false): Promise { if (!this.worker) { return Promise.resolve(UnsuccessfulStart('No worker found: perhaps, CSP is not set.')) } @@ -382,9 +381,19 @@ export default class App { ) } this.activityState = ActivityState.Starting + if (startOpts.sessionHash) { this.session.applySessionHash(startOpts.sessionHash) } + if (startOpts.forceNew) { + // Reset session metadata only if requested directly + this.session.reset() + } + this.session.assign({ + // MBTODO: maybe it would make sense to `forceNew` if the `userID` was changed + userID: startOpts.userID, + metadata: startOpts.metadata, + }) const timestamp = now() this.worker.postMessage({ @@ -397,17 +406,9 @@ export default class App { connAttemptGap: this.options.connAttemptGap, }) - this.session.update({ - // TODO: transparent "session" module logic AND explicit internal api for plugins. - // "updating" with old metadata in order to trigger session's UpdateCallbacks. - // (for the case of internal .start() calls, like on "restart" webworker signal or assistent connection in tracker-assist ) - metadata: startOpts.metadata || this.session.getInfo().metadata, - userID: startOpts.userID, - }) - - const sReset = this.sessionStorage.getItem(this.options.session_reset_key) + const lsReset = this.sessionStorage.getItem(this.options.session_reset_key) !== null this.sessionStorage.removeItem(this.options.session_reset_key) - const shouldReset = startOpts.forceNew || sReset !== null + const needNewSessionID = startOpts.forceNew || lsReset || resetByWorker return window .fetch(this.options.ingestPoint + '/v1/web/start', { @@ -419,7 +420,7 @@ export default class App { ...this.getTrackerInfo(), timestamp, userID: this.session.getInfo().userID, - token: shouldReset ? undefined : this.session.getSessionToken(), + token: needNewSessionID ? undefined : this.session.getSessionToken(), deviceMemory, jsHeapSizeLimit, }), @@ -447,29 +448,33 @@ export default class App { const { token, userUUID, - sessionID, projectID, beaconSizeLimit, - startTimestamp, // real startTS, derived from sessionID - delay, + delay, // derived from token + sessionID, // derived from token + startTimestamp, // real startTS (server time), derived from sessionID } = r if ( typeof token !== 'string' || typeof userUUID !== 'string' || - //typeof startTimestamp !== 'number' || - //typeof sessionID !== 'string' || + (typeof startTimestamp !== 'number' && typeof startTimestamp !== 'undefined') || + typeof sessionID !== 'string' || typeof delay !== 'number' || (typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined') ) { return Promise.reject(`Incorrect server response: ${JSON.stringify(r)}`) } this.delay = delay - const prevSessionID = this.session.getInfo().sessionID - if (prevSessionID && prevSessionID !== sessionID) { - this.session.reset() - } this.session.setSessionToken(token) - this.session.update({ sessionID, timestamp: startTimestamp || timestamp, projectID }) // TODO: no no-explicit 'any' + this.session.assign({ + sessionID, + timestamp: startTimestamp || timestamp, + projectID, + }) + // (Re)send Metadata for the case of a new session + Object.entries(this.session.getInfo().metadata).forEach(([key, value]) => + this.send(Metadata(key, value)), + ) this.localStorage.setItem(this.options.local_uuid_key, userUUID) this.worker.postMessage({ @@ -506,15 +511,15 @@ export default class App { }) } - start(options: StartOptions = {}): Promise { + start(...args: Parameters): Promise { if (!document.hidden) { - return this._start(options) + return this._start(...args) } else { return new Promise((resolve) => { const onVisibilityChange = () => { if (!document.hidden) { document.removeEventListener('visibilitychange', onVisibilityChange) - resolve(this._start(options)) + resolve(this._start(...args)) } } document.addEventListener('visibilitychange', onVisibilityChange) @@ -538,8 +543,4 @@ export default class App { } } } - restart() { - this.stop(false) - this.start({ forceNew: false }) - } } diff --git a/tracker/tracker/src/main/app/session.ts b/tracker/tracker/src/main/app/session.ts index 5c3db5ac5..4682bcc43 100644 --- a/tracker/tracker/src/main/app/session.ts +++ b/tracker/tracker/src/main/app/session.ts @@ -37,7 +37,7 @@ export default class Session { this.callbacks.forEach((cb) => cb(newInfo)) } - update(newInfo: Partial): void { + assign(newInfo: Partial): void { if (newInfo.userID !== undefined) { // TODO clear nullable/undefinable types this.userID = newInfo.userID