1
1
import type { ReplayRecordingData } from '@sentry/types' ;
2
- import { logger } from '@sentry/utils' ;
3
2
4
- import type { AddEventResult , EventBuffer , RecordingEvent , WorkerRequest , WorkerResponse } from '../types' ;
3
+ import type { AddEventResult , EventBuffer , RecordingEvent } from '../types' ;
4
+ import { WorkerHandler } from './WorkerHandler' ;
5
5
6
6
/**
7
7
* Event buffer that uses a web worker to compress events.
@@ -11,57 +11,26 @@ export class EventBufferCompressionWorker implements EventBuffer {
11
11
/** @inheritdoc */
12
12
public hasEvents : boolean ;
13
13
14
- private _worker : Worker ;
15
- private _id : number ;
16
- private _ensureReadyPromise ?: Promise < void > ;
14
+ private _worker : WorkerHandler ;
17
15
18
16
public constructor ( worker : Worker ) {
19
- this . _worker = worker ;
17
+ this . _worker = new WorkerHandler ( worker ) ;
20
18
this . hasEvents = false ;
21
- this . _id = 0 ;
22
19
}
23
20
24
21
/**
25
22
* Ensure the worker is ready (or not).
26
23
* This will either resolve when the worker is ready, or reject if an error occured.
27
24
*/
28
25
public ensureReady ( ) : Promise < void > {
29
- // Ensure we only check once
30
- if ( this . _ensureReadyPromise ) {
31
- return this . _ensureReadyPromise ;
32
- }
33
-
34
- this . _ensureReadyPromise = new Promise ( ( resolve , reject ) => {
35
- this . _worker . addEventListener (
36
- 'message' ,
37
- ( { data } : MessageEvent ) => {
38
- if ( ( data as WorkerResponse ) . success ) {
39
- resolve ( ) ;
40
- } else {
41
- reject ( ) ;
42
- }
43
- } ,
44
- { once : true } ,
45
- ) ;
46
-
47
- this . _worker . addEventListener (
48
- 'error' ,
49
- error => {
50
- reject ( error ) ;
51
- } ,
52
- { once : true } ,
53
- ) ;
54
- } ) ;
55
-
56
- return this . _ensureReadyPromise ;
26
+ return this . _worker . ensureReady ( ) ;
57
27
}
58
28
59
29
/**
60
30
* Destroy the event buffer.
61
31
*/
62
32
public destroy ( ) : void {
63
- __DEBUG_BUILD__ && logger . log ( '[Replay] Destroying compression worker' ) ;
64
- this . _worker . terminate ( ) ;
33
+ this . _worker . destroy ( ) ;
65
34
}
66
35
67
36
/**
@@ -75,10 +44,7 @@ export class EventBufferCompressionWorker implements EventBuffer {
75
44
if ( isCheckout ) {
76
45
// This event is a checkout, make sure worker buffer is cleared before
77
46
// proceeding.
78
- await this . _postMessage ( {
79
- id : this . _getAndIncrementId ( ) ,
80
- method : 'clear' ,
81
- } ) ;
47
+ await this . _clear ( ) ;
82
48
}
83
49
84
50
return this . _sendEventToWorker ( event ) ;
@@ -88,71 +54,29 @@ export class EventBufferCompressionWorker implements EventBuffer {
88
54
* Finish the event buffer and return the compressed data.
89
55
*/
90
56
public finish ( ) : Promise < ReplayRecordingData > {
91
- return this . _finishRequest ( this . _getAndIncrementId ( ) ) ;
92
- }
93
-
94
- /**
95
- * Post message to worker and wait for response before resolving promise.
96
- */
97
- private _postMessage < T > ( { id, method, arg } : WorkerRequest ) : Promise < T > {
98
- return new Promise ( ( resolve , reject ) => {
99
- const listener = ( { data } : MessageEvent ) : void => {
100
- const response = data as WorkerResponse ;
101
- if ( response . method !== method ) {
102
- return ;
103
- }
104
-
105
- // There can be multiple listeners for a single method, the id ensures
106
- // that the response matches the caller.
107
- if ( response . id !== id ) {
108
- return ;
109
- }
110
-
111
- // At this point, we'll always want to remove listener regardless of result status
112
- this . _worker . removeEventListener ( 'message' , listener ) ;
113
-
114
- if ( ! response . success ) {
115
- // TODO: Do some error handling, not sure what
116
- __DEBUG_BUILD__ && logger . error ( '[Replay]' , response . response ) ;
117
-
118
- reject ( new Error ( 'Error in compression worker' ) ) ;
119
- return ;
120
- }
121
-
122
- resolve ( response . response as T ) ;
123
- } ;
124
-
125
- // Note: we can't use `once` option because it's possible it needs to
126
- // listen to multiple messages
127
- this . _worker . addEventListener ( 'message' , listener ) ;
128
- this . _worker . postMessage ( { id, method, arg } ) ;
129
- } ) ;
57
+ return this . _finishRequest ( ) ;
130
58
}
131
59
132
60
/**
133
61
* Send the event to the worker.
134
62
*/
135
63
private _sendEventToWorker ( event : RecordingEvent ) : Promise < AddEventResult > {
136
- return this . _postMessage < void > ( {
137
- id : this . _getAndIncrementId ( ) ,
138
- method : 'addEvent' ,
139
- arg : JSON . stringify ( event ) ,
140
- } ) ;
64
+ return this . _worker . postMessage < void > ( 'addEvent' , JSON . stringify ( event ) ) ;
141
65
}
142
66
143
67
/**
144
68
* Finish the request and return the compressed data from the worker.
145
69
*/
146
- private async _finishRequest ( id : number ) : Promise < Uint8Array > {
147
- const response = await this . _postMessage < Uint8Array > ( { id , method : 'finish' } ) ;
70
+ private async _finishRequest ( ) : Promise < Uint8Array > {
71
+ const response = await this . _worker . postMessage < Uint8Array > ( 'finish' ) ;
148
72
149
73
this . hasEvents = false ;
150
74
151
75
return response ;
152
76
}
153
77
154
- /** Get the current ID and increment it for the next call . */
155
- private _getAndIncrementId ( ) : number {
156
- return this . _id ++ ;
78
+ /** Clear any pending events from the worker . */
79
+ private _clear ( ) : Promise < void > {
80
+ return this . _worker . postMessage ( 'clear' ) ;
157
81
}
158
82
}
0 commit comments