1
+ /* eslint-disable max-lines */
1
2
import { Hub } from '@sentry/hub' ;
2
3
import { TransactionContext } from '@sentry/types' ;
3
4
import { getGlobalObject , logger , timestampWithMs } from '@sentry/utils' ;
@@ -7,6 +8,7 @@ import { Span, SpanRecorder } from './span';
7
8
import { Transaction } from './transaction' ;
8
9
9
10
export const DEFAULT_IDLE_TIMEOUT = 1000 ;
11
+ export const DEFAULT_FINAL_TIMEOUT = 30000 ;
10
12
export const HEARTBEAT_INTERVAL = 5000 ;
11
13
12
14
const global = getGlobalObject < Window > ( ) ;
@@ -73,18 +75,29 @@ export class IdleTransaction extends Transaction {
73
75
* If a transaction is created and no activities are added, we want to make sure that
74
76
* it times out properly. This is cleared and not used when activities are added.
75
77
*/
76
- private _initTimeout : ReturnType < typeof global . setTimeout > | undefined ;
78
+ private _idleTimeoutID : ReturnType < typeof global . setTimeout > | undefined ;
77
79
78
80
public constructor (
79
81
transactionContext : TransactionContext ,
80
82
private readonly _idleHub ?: Hub ,
81
83
/**
82
84
* The time to wait in ms until the idle transaction will be finished.
83
85
* @default 1000
86
+ *
87
+ * TODO: Make _idleTimeout and _finalTimeout required to reduce duplication when setting the options
88
+ * in `BrowserTracing`. This is considered a breaking change to the IdleTransaction API,
89
+ * so we need to make sure we communicate it with react native.
84
90
*/
85
91
private readonly _idleTimeout : number = DEFAULT_IDLE_TIMEOUT ,
86
92
// Whether or not the transaction should put itself on the scope when it starts and pop itself off when it ends
87
93
private readonly _onScope : boolean = false ,
94
+ /**
95
+ * The final value that a transaction cannot exceed
96
+ * @default 15000
97
+ * @experimental
98
+ * @internal
99
+ */
100
+ private readonly _finalTimeout : number = DEFAULT_FINAL_TIMEOUT ,
88
101
) {
89
102
super ( transactionContext , _idleHub ) ;
90
103
@@ -98,11 +111,13 @@ export class IdleTransaction extends Transaction {
98
111
_idleHub . configureScope ( scope => scope . setSpan ( this ) ) ;
99
112
}
100
113
101
- this . _initTimeout = global . setTimeout ( ( ) => {
114
+ this . _startIdleTimeout ( ) ;
115
+ global . setTimeout ( ( ) => {
102
116
if ( ! this . _finished ) {
117
+ this . setTag ( FINISH_REASON_TAG , IDLE_TRANSACTION_FINISH_REASONS [ 3 ] ) ;
103
118
this . finish ( ) ;
104
119
}
105
- } , this . _idleTimeout ) ;
120
+ } , this . _finalTimeout ) ;
106
121
}
107
122
108
123
/** {@inheritDoc } */
@@ -191,15 +206,35 @@ export class IdleTransaction extends Transaction {
191
206
this . spanRecorder . add ( this ) ;
192
207
}
193
208
209
+ /**
210
+ * Creates an idletimeout
211
+ */
212
+ private _cancelIdleTimeout ( ) : void {
213
+ if ( this . _idleTimeoutID ) {
214
+ global . clearTimeout ( this . _idleTimeoutID ) ;
215
+ this . _idleTimeoutID = undefined ;
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Creates an idletimeout
221
+ */
222
+ private _startIdleTimeout ( end ?: Parameters < IdleTransaction [ 'finish' ] > [ 0 ] ) : void {
223
+ this . _cancelIdleTimeout ( ) ;
224
+ this . _idleTimeoutID = global . setTimeout ( ( ) => {
225
+ if ( ! this . _finished && Object . keys ( this . activities ) . length === 0 ) {
226
+ this . setTag ( FINISH_REASON_TAG , IDLE_TRANSACTION_FINISH_REASONS [ 1 ] ) ;
227
+ this . finish ( end ) ;
228
+ }
229
+ } , this . _idleTimeout ) ;
230
+ }
231
+
194
232
/**
195
233
* Start tracking a specific activity.
196
234
* @param spanId The span id that represents the activity
197
235
*/
198
236
private _pushActivity ( spanId : string ) : void {
199
- if ( this . _initTimeout ) {
200
- clearTimeout ( this . _initTimeout ) ;
201
- this . _initTimeout = undefined ;
202
- }
237
+ this . _cancelIdleTimeout ( ) ;
203
238
logger . log ( `[Tracing] pushActivity: ${ spanId } ` ) ;
204
239
this . activities [ spanId ] = true ;
205
240
logger . log ( '[Tracing] new activities count' , Object . keys ( this . activities ) . length ) ;
@@ -222,13 +257,7 @@ export class IdleTransaction extends Transaction {
222
257
// We need to add the timeout here to have the real endtimestamp of the transaction
223
258
// Remember timestampWithMs is in seconds, timeout is in ms
224
259
const end = timestampWithMs ( ) + timeout / 1000 ;
225
-
226
- global . setTimeout ( ( ) => {
227
- if ( ! this . _finished ) {
228
- this . setTag ( FINISH_REASON_TAG , IDLE_TRANSACTION_FINISH_REASONS [ 1 ] ) ;
229
- this . finish ( end ) ;
230
- }
231
- } , timeout ) ;
260
+ this . _startIdleTimeout ( end ) ;
232
261
}
233
262
}
234
263
0 commit comments