From a0db19edb078054c7f544dfad8f3868686d6fef6 Mon Sep 17 00:00:00 2001 From: Alex Kaminskii Date: Wed, 19 Oct 2022 18:57:51 +0200 Subject: [PATCH] feat(tracker):4.1.6: server-time sync on start --- backend/internal/http/router/handlers-web.go | 2 +- tracker/tracker/package.json | 2 +- tracker/tracker/src/main/app/index.ts | 19 ++++++++++++++----- tracker/tracker/src/main/modules/img.ts | 4 ++-- tracker/tracker/src/main/utils.ts | 2 +- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/backend/internal/http/router/handlers-web.go b/backend/internal/http/router/handlers-web.go index 3e1394d9e..08c4c75c5 100644 --- a/backend/internal/http/router/handlers-web.go +++ b/backend/internal/http/router/handlers-web.go @@ -40,7 +40,7 @@ func (e *Router) readBody(w http.ResponseWriter, r *http.Request, limit int64) ( func getSessionTimestamp(req *StartSessionRequest, startTimeMili int64) (ts uint64) { ts = uint64(req.Timestamp) - c, err := semver.NewConstraint(">=4.2.0") // ) + c, err := semver.NewConstraint(">=4.1.6") if err != nil { return } diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index e748cc15a..0913d0978 100644 --- a/tracker/tracker/package.json +++ b/tracker/tracker/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker", "description": "The OpenReplay tracker main package", - "version": "4.1.5", + "version": "4.1.6", "keywords": [ "logging", "replay" diff --git a/tracker/tracker/src/main/app/index.ts b/tracker/tracker/src/main/app/index.ts index 95ddd83d0..5f280ead4 100644 --- a/tracker/tracker/src/main/app/index.ts +++ b/tracker/tracker/src/main/app/index.ts @@ -1,6 +1,6 @@ import type Message from './messages.gen.js' import { Timestamp, Metadata, UserID } from './messages.gen.js' -import { timestamp as now, deprecationWarn } from '../utils.js' +import { now, deprecationWarn } from '../utils.js' import Nodes from './nodes.js' import Observer from './observer/top_observer.js' import Sanitizer from './sanitizer.js' @@ -205,22 +205,28 @@ export default class App { } this.messages.push(message) // TODO: commit on start if there were `urgent` sends; - // Clearify where urgent can be used for; - // Clearify workflow for each type of message in case it was sent before start + // Clarify where urgent can be used for; + // Clarify workflow for each type of message in case it was sent before start // (like Fetch before start; maybe add an option "preCapture: boolean" or sth alike) + // Careful: `this.delay` is equal to zero before start hense all Timestamp-s will have to be updated on start if (this.activityState === ActivityState.Active && urgent) { this.commit() } } private commit(): void { if (this.worker && this.messages.length) { - this.messages.unshift(Timestamp(now())) + this.messages.unshift(Timestamp(this.timestamp())) this.worker.postMessage(this.messages) this.commitCallbacks.forEach((cb) => cb(this.messages)) this.messages.length = 0 } } + private delay = 0 + timestamp(): number { + return now() + this.delay + } + safe void>(fn: T): T { const app = this return function (this: any, ...args: any[]) { @@ -228,7 +234,7 @@ export default class App { fn.apply(this, args) } catch (e) { app._debug('safe_fn_call', e) - // time: now(), + // time: this.timestamp(), // name: e.name, // message: e.message, // stack: e.stack @@ -444,16 +450,19 @@ export default class App { projectID, beaconSizeLimit, startTimestamp, // real startTS, derived from sessionID + delay, } = r if ( typeof token !== 'string' || typeof userUUID !== 'string' || //typeof startTimestamp !== 'number' || //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() diff --git a/tracker/tracker/src/main/modules/img.ts b/tracker/tracker/src/main/modules/img.ts index b2c699167..c6dedc6e0 100644 --- a/tracker/tracker/src/main/modules/img.ts +++ b/tracker/tracker/src/main/modules/img.ts @@ -1,5 +1,5 @@ import type App from '../app/index.js' -import { timestamp, isURL, IS_FIREFOX, MAX_STR_LEN } from '../utils.js' +import { isURL, IS_FIREFOX, MAX_STR_LEN } from '../utils.js' import { ResourceTiming, SetNodeAttributeURLBased, SetNodeAttribute } from '../app/messages.gen.js' import { hasTag } from '../app/guards.js' @@ -59,7 +59,7 @@ export default function (app: App): void { const sendImgError = app.safe(function (img: HTMLImageElement): void { const resolvedSrc = resolveURL(img.src || '') // Src type is null sometimes. - is it true? if (isURL(resolvedSrc)) { - app.send(ResourceTiming(timestamp(), 0, 0, 0, 0, 0, resolvedSrc, 'img')) + app.send(ResourceTiming(app.timestamp(), 0, 0, 0, 0, 0, resolvedSrc, 'img')) } }) diff --git a/tracker/tracker/src/main/utils.ts b/tracker/tracker/src/main/utils.ts index dfff3d8e5..8ed47096d 100644 --- a/tracker/tracker/src/main/utils.ts +++ b/tracker/tracker/src/main/utils.ts @@ -9,7 +9,7 @@ export const MAX_STR_LEN = 1e5 const navigationStart: number | false = IN_BROWSER && (performance.timing.navigationStart || performance.timeOrigin) // performance.now() is buggy in some browsers -export const timestamp: () => number = +export const now: () => number = IN_BROWSER && performance.now() && navigationStart ? () => Math.round(performance.now() + navigationStart) : () => Date.now()