refactor(tracker): WebWorker interactions typification
This commit is contained in:
parent
2b6642778a
commit
bb09e7f2ed
4 changed files with 38 additions and 23 deletions
|
|
@ -19,4 +19,11 @@ type Auth = {
|
|||
beaconSizeLimit?: number
|
||||
}
|
||||
|
||||
export type WorkerMessageData = null | 'stop' | Start | Auth | Array<Message>
|
||||
export type ToWorkerData = null | 'stop' | Start | Auth | Array<Message>
|
||||
|
||||
type Failure = {
|
||||
type: 'failure'
|
||||
reason: string
|
||||
}
|
||||
|
||||
export type FromWorkerData = 'restart' | Failure
|
||||
|
|
|
|||
|
|
@ -14,7 +14,15 @@ import type { Options as ObserverOptions } from './observer/top_observer.js'
|
|||
import type { Options as SanitizerOptions } from './sanitizer.js'
|
||||
import type { Options as LoggerOptions } from './logger.js'
|
||||
import type { Options as SessOptions } from './session.js'
|
||||
import type { Options as WebworkerOptions, WorkerMessageData } from '../../common/interaction.js'
|
||||
import type {
|
||||
Options as WebworkerOptions,
|
||||
ToWorkerData,
|
||||
FromWorkerData,
|
||||
} from '../../common/interaction.js'
|
||||
|
||||
interface TypedWorker extends Omit<Worker, 'postMessage'> {
|
||||
postMessage(data: ToWorkerData): void
|
||||
}
|
||||
|
||||
// TODO: Unify and clearly describe options logic
|
||||
export interface StartOptions {
|
||||
|
|
@ -94,7 +102,7 @@ export default class App {
|
|||
private readonly revID: string
|
||||
private activityState: ActivityState = ActivityState.NotActive
|
||||
private readonly version = 'TRACKER_VERSION' // TODO: version compatability check inside each plugin.
|
||||
private readonly worker?: Worker
|
||||
private readonly worker?: TypedWorker
|
||||
constructor(projectKey: string, sessionToken: string | undefined, options: Partial<Options>) {
|
||||
// if (options.onStart !== undefined) {
|
||||
// deprecationWarn("'onStart' option", "tracker.start().then(/* handle session info */)")
|
||||
|
|
@ -153,13 +161,13 @@ export default class App {
|
|||
this.worker.onerror = (e) => {
|
||||
this._debug('webworker_error', e)
|
||||
}
|
||||
this.worker.onmessage = ({ data }: MessageEvent) => {
|
||||
if (data === 'failed') {
|
||||
this.stop(false)
|
||||
this._debug('worker_failed', {}) // add context (from worker)
|
||||
} else if (data === 'restart') {
|
||||
this.worker.onmessage = ({ data }: MessageEvent<FromWorkerData>) => {
|
||||
if (data === 'restart') {
|
||||
this.stop(false)
|
||||
this.start({ forceNew: true }) // TODO: keep userID & metadata (draw scenarios)
|
||||
} else if (data.type === 'failure') {
|
||||
this.stop(false)
|
||||
this._debug('worker_failed', data.reason)
|
||||
}
|
||||
}
|
||||
const alertWorker = () => {
|
||||
|
|
@ -372,7 +380,7 @@ export default class App {
|
|||
}
|
||||
|
||||
const timestamp = now()
|
||||
const startWorkerMsg: WorkerMessageData = {
|
||||
this.worker.postMessage({
|
||||
type: 'start',
|
||||
pageNo: this.session.incPageNo(),
|
||||
ingestPoint: this.options.ingestPoint,
|
||||
|
|
@ -380,8 +388,7 @@ export default class App {
|
|||
url: document.URL,
|
||||
connAttemptCount: this.options.connAttemptCount,
|
||||
connAttemptGap: this.options.connAttemptGap,
|
||||
}
|
||||
this.worker.postMessage(startWorkerMsg)
|
||||
})
|
||||
|
||||
this.session.update({
|
||||
// TODO: transparent "session" module logic AND explicit internal api for plugins.
|
||||
|
|
@ -455,12 +462,11 @@ export default class App {
|
|||
this.session.update({ sessionID, timestamp: startTimestamp || timestamp, projectID }) // TODO: no no-explicit 'any'
|
||||
this.localStorage.setItem(this.options.local_uuid_key, userUUID)
|
||||
|
||||
const startWorkerMsg: WorkerMessageData = {
|
||||
this.worker.postMessage({
|
||||
type: 'auth',
|
||||
token,
|
||||
beaconSizeLimit,
|
||||
}
|
||||
this.worker.postMessage(startWorkerMsg)
|
||||
})
|
||||
|
||||
const onStartInfo = { sessionToken: token, userUUID, sessionID }
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export default class QueueSender {
|
|||
constructor(
|
||||
ingestBaseURL: string,
|
||||
private readonly onUnauthorised: () => any,
|
||||
private readonly onFailure: () => any,
|
||||
private readonly onFailure: (reason: string) => any,
|
||||
private readonly MAX_ATTEMPTS_COUNT = 10,
|
||||
private readonly ATTEMPT_TIMEOUT = 1000,
|
||||
) {
|
||||
|
|
@ -50,7 +50,7 @@ export default class QueueSender {
|
|||
|
||||
private retry(batch: Uint8Array): void {
|
||||
if (this.attemptsCount >= this.MAX_ATTEMPTS_COUNT) {
|
||||
this.onFailure()
|
||||
this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`)
|
||||
return
|
||||
}
|
||||
this.attemptsCount++
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import type Message from '../common/messages.gen.js'
|
||||
import { Type as MType } from '../common/messages.gen.js'
|
||||
import { WorkerMessageData } from '../common/interaction.js'
|
||||
import { ToWorkerData, FromWorkerData } from '../common/interaction.js'
|
||||
|
||||
import QueueSender from './QueueSender.js'
|
||||
import BatchWriter from './BatchWriter.js'
|
||||
|
||||
declare function postMessage(message: FromWorkerData): void
|
||||
|
||||
enum WorkerStatus {
|
||||
NotActive,
|
||||
Starting,
|
||||
|
|
@ -51,18 +53,18 @@ function reset(): void {
|
|||
}
|
||||
|
||||
function initiateRestart(): void {
|
||||
self.postMessage('restart')
|
||||
postMessage('restart')
|
||||
reset()
|
||||
}
|
||||
function initiateFailure(): void {
|
||||
self.postMessage('failed')
|
||||
function initiateFailure(reason: string): void {
|
||||
postMessage({ type: 'failure', reason })
|
||||
reset()
|
||||
}
|
||||
|
||||
let sendIntervalID: ReturnType<typeof setInterval> | null = null
|
||||
let restartTimeoutID: ReturnType<typeof setTimeout>
|
||||
|
||||
self.onmessage = ({ data }: MessageEvent<WorkerMessageData>): any => {
|
||||
self.onmessage = ({ data }: MessageEvent<ToWorkerData>): any => {
|
||||
if (data == null) {
|
||||
finalize()
|
||||
return
|
||||
|
|
@ -101,9 +103,9 @@ self.onmessage = ({ data }: MessageEvent<WorkerMessageData>): any => {
|
|||
// onUnauthorised
|
||||
initiateRestart()
|
||||
},
|
||||
() => {
|
||||
(reason) => {
|
||||
// onFailure
|
||||
initiateFailure()
|
||||
initiateFailure(reason)
|
||||
},
|
||||
data.connAttemptCount,
|
||||
data.connAttemptGap,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue