1
1
import { EventProcessor , Hub , Integration , Scope , Span , SpanContext } from '@sentry/types' ;
2
- import { timestampWithMs } from '@sentry/utils' ;
3
2
4
3
/** JSDoc */
5
4
interface TransactionActivityOptions {
@@ -11,7 +10,7 @@ interface TransactionActivityOptions {
11
10
// onActivity?: (info) => {
12
11
// return info.type !== 'xhr' || !info.url.match(/zendesk/);
13
12
// },
14
- idleTimeout ? : number ;
13
+ idleTimeout : number ;
15
14
}
16
15
17
16
/** JSDoc */
@@ -51,11 +50,12 @@ export class TransactionActivity implements Integration {
51
50
/**
52
51
* @inheritDoc
53
52
*/
54
- public constructor ( options ?: TransactionActivityOptions ) {
55
- TransactionActivity . _options = {
53
+ public constructor (
54
+ public readonly _options : TransactionActivityOptions = {
56
55
idleTimeout : 500 ,
57
- ...options ,
58
- } ;
56
+ } ,
57
+ ) {
58
+ TransactionActivity . _options = _options ;
59
59
}
60
60
61
61
/**
@@ -65,35 +65,16 @@ export class TransactionActivity implements Integration {
65
65
TransactionActivity . _getCurrentHub = getCurrentHub ;
66
66
}
67
67
68
- /**
69
- * Internal run loop that checks if activy is running
70
- */
71
- private static _watchActivity ( ) : void {
72
- const count = Object . keys ( TransactionActivity . _activities ) . length ;
73
- clearTimeout ( TransactionActivity . _debounce ) ;
74
- if ( count > 0 ) {
75
- setTimeout ( ( ) => {
76
- TransactionActivity . _watchActivity ( ) ;
77
- } , 10 ) ;
78
- } else {
79
- const timeout = TransactionActivity . _options && TransactionActivity . _options . idleTimeout ;
80
- TransactionActivity . _debounce = ( setTimeout ( ( ) => {
81
- const active = TransactionActivity . _activeTransaction ;
82
- if ( active ) {
83
- active . finish ( timestampWithMs ( ) - ( timeout || 0 ) ) ;
84
- }
85
- } , timeout ) as any ) as number ; // TODO 500
86
- }
87
- }
88
-
89
68
/**
90
69
* Starts a Transaction waiting for activity idle to finish
91
70
*/
92
71
public static startIdleTransaction ( name : string , spanContext ?: SpanContext ) : Span | undefined {
93
72
const activeTransaction = TransactionActivity . _activeTransaction ;
94
73
95
74
if ( activeTransaction ) {
96
- // We need to finish any active transaction before starting a new
75
+ // If we already have an active transaction it means one of two things
76
+ // a) The user did rapid navigation changes and didn't wait until the transaction was finished
77
+ // b) A activity wasn't popped correctly and therefore the transaction is stalling
97
78
activeTransaction . finish ( ) ;
98
79
}
99
80
@@ -107,17 +88,27 @@ export class TransactionActivity implements Integration {
107
88
return undefined ;
108
89
}
109
90
110
- const span = hub . startSpan ( {
111
- ...spanContext ,
112
- transaction : name ,
113
- } ) ;
91
+ const span = hub . startSpan (
92
+ {
93
+ ...spanContext ,
94
+ transaction : name ,
95
+ } ,
96
+ true ,
97
+ ) ;
114
98
115
99
TransactionActivity . _activeTransaction = span ;
116
100
117
101
hub . configureScope ( ( scope : Scope ) => {
118
102
scope . setSpan ( span ) ;
119
103
} ) ;
120
104
105
+ // The reason we do this here is because of cached responses
106
+ // If we start and transaction without an activity it would never finish since there is no activity
107
+ const id = TransactionActivity . pushActivity ( 'idleTransactionStarted' ) ;
108
+ setTimeout ( ( ) => {
109
+ TransactionActivity . popActivity ( id ) ;
110
+ } , ( TransactionActivity . _options && TransactionActivity . _options . idleTimeout ) || 100 ) ;
111
+
121
112
return span ;
122
113
}
123
114
@@ -152,7 +143,6 @@ export class TransactionActivity implements Integration {
152
143
} ;
153
144
}
154
145
155
- TransactionActivity . _watchActivity ( ) ;
156
146
return TransactionActivity . _currentIndex ++ ;
157
147
}
158
148
@@ -168,5 +158,18 @@ export class TransactionActivity implements Integration {
168
158
// tslint:disable-next-line: no-dynamic-delete
169
159
delete TransactionActivity . _activities [ id ] ;
170
160
}
161
+
162
+ const count = Object . keys ( TransactionActivity . _activities ) . length ;
163
+ clearTimeout ( TransactionActivity . _debounce ) ;
164
+
165
+ if ( count === 0 ) {
166
+ const timeout = TransactionActivity . _options && TransactionActivity . _options . idleTimeout ;
167
+ TransactionActivity . _debounce = ( setTimeout ( ( ) => {
168
+ const active = TransactionActivity . _activeTransaction ;
169
+ if ( active ) {
170
+ active . finish ( true ) ;
171
+ }
172
+ } , timeout ) as any ) as number ; // TODO 500
173
+ }
171
174
}
172
175
}
0 commit comments