11// tslint:disable:max-classes-per-file
22import { Hub } from '@sentry/hub' ;
33import { TransactionContext } from '@sentry/types' ;
4- import { timestampWithMs , logger } from '@sentry/utils' ;
4+ import { logger , timestampWithMs } from '@sentry/utils' ;
55
66import { Span } from './span' ;
77import { SpanStatus } from './spanstatus' ;
88import { SpanRecorder , Transaction } from './transaction' ;
9- import { BrowserTracing } from './integrations/browsertracing' ;
109
1110/**
1211 * @inheritDoc
1312 */
14- class IdleTransactionSpanRecorder extends SpanRecorder {
13+ export class IdleTransactionSpanRecorder extends SpanRecorder {
1514 private readonly _pushActivity ?: ( id : string ) => void ;
1615 private readonly _popActivity ?: ( id : string ) => void ;
1716
@@ -25,8 +24,10 @@ class IdleTransactionSpanRecorder extends SpanRecorder {
2524 * @inheritDoc
2625 */
2726 public add ( span : Span ) : void {
27+ // tslint:disable-next-line: no-unbound-method
28+ const oldFinish : Function = span . finish ;
2829 span . finish = ( endTimestamp ?: number ) => {
29- span . finish ( endTimestamp ) ;
30+ oldFinish ( endTimestamp ) ;
3031 if ( this . _popActivity ) {
3132 this . _popActivity ( span . spanId ) ;
3233 }
@@ -47,7 +48,7 @@ export class IdleTransaction extends Transaction {
4748 /**
4849 * Activities store a list of active spans
4950 */
50- public _activities : Record < string , boolean > = { } ;
51+ public activities : Record < string , boolean > = { } ;
5152
5253 private _heartbeatTimer : number = 0 ;
5354
@@ -64,32 +65,34 @@ export class IdleTransaction extends Transaction {
6465 }
6566
6667 /**
67- * Checks when entries of this._activities are not changing for 3 beats.
68+ * Checks when entries of this.activities are not changing for 3 beats.
6869 * If this occurs we finish the transaction.
6970 */
7071 private _beat ( ) : void {
7172 clearTimeout ( this . _heartbeatTimer ) ;
72- const keys = Object . keys ( this . _activities ) ;
73- if ( keys . length ) {
74- const heartbeatString = keys . reduce ( ( prev : string , current : string ) => prev + current ) ;
75- if ( heartbeatString === this . _prevHeartbeatString ) {
76- this . _heartbeatCounter ++ ;
77- } else {
78- this . _heartbeatCounter = 0 ;
79- }
80- if ( this . _heartbeatCounter >= 3 ) {
81- logger . log (
82- `[Tracing] Transaction: ${
83- SpanStatus . Cancelled
84- } -> Heartbeat safeguard kicked in since content hasn't changed for 3 beats`,
85- ) ;
86- this . setStatus ( SpanStatus . DeadlineExceeded ) ;
87- this . setTag ( 'heartbeat' , 'failed' ) ;
88- this . _finishIdleTransaction ( timestampWithMs ( ) ) ;
89- }
90- this . _prevHeartbeatString = heartbeatString ;
73+ const keys = Object . keys ( this . activities ) ;
74+ const heartbeatString = keys . length ? keys . reduce ( ( prev : string , current : string ) => prev + current ) : '' ;
75+
76+ if ( heartbeatString === this . _prevHeartbeatString ) {
77+ this . _heartbeatCounter ++ ;
78+ } else {
79+ this . _heartbeatCounter = 1 ;
80+ }
81+
82+ this . _prevHeartbeatString = heartbeatString ;
83+
84+ if ( this . _heartbeatCounter >= 3 ) {
85+ logger . log (
86+ `[Tracing] Transaction: ${
87+ SpanStatus . Cancelled
88+ } -> Heartbeat safeguard kicked in since content hasn't changed for 3 beats`,
89+ ) ;
90+ this . setStatus ( SpanStatus . DeadlineExceeded ) ;
91+ this . setTag ( 'heartbeat' , 'failed' ) ;
92+ this . _finishIdleTransaction ( timestampWithMs ( ) ) ;
93+ } else {
94+ this . _pingHeartbeat ( ) ;
9195 }
92- this . _pingHeartbeat ( ) ;
9396 }
9497
9598 /**
@@ -131,6 +134,7 @@ export class IdleTransaction extends Transaction {
131134
132135 logger . log ( '[Tracing] flushing IdleTransaction' ) ;
133136 this . finish ( ) ;
137+ this . _finished = true ;
134138 } else {
135139 logger . log ( '[Tracing] No active IdleTransaction' ) ;
136140 }
@@ -141,20 +145,20 @@ export class IdleTransaction extends Transaction {
141145 * @param spanId The span id that represents the activity
142146 */
143147 private _pushActivity ( spanId : string ) : void {
144- this . _activities [ spanId ] = true ;
148+ this . activities [ spanId ] = true ;
145149 }
146150
147151 /**
148152 * Remove an activity from usage
149153 * @param spanId The span id that represents the activity
150154 */
151155 private _popActivity ( spanId : string ) : void {
152- if ( this . _activities [ spanId ] ) {
156+ if ( this . activities [ spanId ] ) {
153157 // tslint:disable-next-line: no-dynamic-delete
154- delete this . _activities [ spanId ] ;
158+ delete this . activities [ spanId ] ;
155159 }
156160
157- const count = Object . keys ( this . _activities ) . length ;
161+ const count = Object . keys ( this . activities ) . length ;
158162 if ( count === 0 ) {
159163 const timeout = this . _idleTimeout ;
160164 // We need to add the timeout here to have the real endtimestamp of the transaction
@@ -171,8 +175,18 @@ export class IdleTransaction extends Transaction {
171175 */
172176 public initSpanRecorder ( maxlen ?: number ) : void {
173177 if ( ! this . spanRecorder ) {
178+ const pushActivity = ( id : string ) => {
179+ if ( id !== this . spanId ) {
180+ this . _pushActivity ( id ) ;
181+ }
182+ } ;
183+ const popActivity = ( id : string ) => {
184+ if ( id !== this . spanId ) {
185+ this . _popActivity ( id ) ;
186+ }
187+ } ;
174188 // tslint:disable-next-line: no-unbound-method
175- this . spanRecorder = new IdleTransactionSpanRecorder ( maxlen , this . _popActivity , this . _pushActivity ) ;
189+ this . spanRecorder = new IdleTransactionSpanRecorder ( maxlen , pushActivity , popActivity ) ;
176190 }
177191 this . spanRecorder . add ( this ) ;
178192 }
0 commit comments