7
7
logger ,
8
8
safeJoin ,
9
9
supportsNativeFetch ,
10
+ timestampWithMs ,
10
11
} from '@sentry/utils' ;
11
12
12
13
import { Span as SpanClass } from '../span' ;
@@ -60,10 +61,8 @@ interface TracingOptions {
60
61
startTransactionOnLocationChange : boolean ;
61
62
62
63
/**
63
- * The maximum duration of a transaction before it will be discarded. This is for some edge cases where a browser
64
- * completely freezes the JS state and picks it up later (background tabs).
65
- * So after this duration, the SDK will not send the event.
66
- * If you want to have an unlimited duration set it to 0.
64
+ * The maximum duration of a transaction before it will be marked as "deadline_exceeded".
65
+ * If you never want to mark a transaction set it to 0.
67
66
* Time is in seconds.
68
67
*
69
68
* Default: 600
@@ -138,7 +137,7 @@ export class Tracing implements Integration {
138
137
139
138
public static _activities : { [ key : number ] : Activity } = { } ;
140
139
141
- private static _debounce : number = 0 ;
140
+ private static _idleTransactionEndTimestamp : number = 0 ;
142
141
143
142
private readonly _emitOptionsWarning : boolean = false ;
144
143
@@ -419,7 +418,7 @@ export class Tracing implements Integration {
419
418
// b) A activity wasn't popped correctly and therefore the transaction is stalling
420
419
Tracing . finishIdleTransaction ( ) ;
421
420
422
- Tracing . _log ( '[Tracing] startIdleTransaction, name:' , transactionContext . name ) ;
421
+ Tracing . _log ( '[Tracing] startIdleTransaction' ) ;
423
422
424
423
const _getCurrentHub = Tracing . _getCurrentHub ;
425
424
if ( ! _getCurrentHub ) {
@@ -453,7 +452,21 @@ export class Tracing implements Integration {
453
452
const active = Tracing . _activeTransaction ;
454
453
if ( active ) {
455
454
Tracing . _addPerformanceEntries ( active ) ;
456
- Tracing . _log ( '[Tracing] finishIdleTransaction' , active . name ) ;
455
+ Tracing . _log ( '[Tracing] finishIdleTransaction' ) ;
456
+
457
+ if ( active . spanRecorder ) {
458
+ const timeout = ( Tracing . options && Tracing . options . idleTimeout ) || 100 ;
459
+ active . spanRecorder . spans = active . spanRecorder . spans . filter ( ( finishedSpan : Span ) => {
460
+ const keepSpan = finishedSpan . startTimestamp < Tracing . _idleTransactionEndTimestamp + timeout ;
461
+ if ( ! keepSpan ) {
462
+ Tracing . _log (
463
+ '[Tracing] discarding Span since it happened after Transaction was finished' ,
464
+ finishedSpan . toJSON ( ) ,
465
+ ) ;
466
+ }
467
+ return keepSpan ;
468
+ } ) ;
469
+ }
457
470
active . finish ( ) ;
458
471
Tracing . _resetActiveTransaction ( ) ;
459
472
}
@@ -477,7 +490,7 @@ export class Tracing implements Integration {
477
490
const timeOrigin = Tracing . _msToSec ( performance . timeOrigin ) ;
478
491
479
492
// tslint:disable-next-line: completed-docs
480
- function addPerformanceNavigationTiming ( parent : SpanClass , entry : { [ key : string ] : number } , event : string ) : void {
493
+ function addPerformanceNavigationTiming ( parent : Span , entry : { [ key : string ] : number } , event : string ) : void {
481
494
const span = parent . startChild ( {
482
495
description : event ,
483
496
op : 'browser' ,
@@ -487,7 +500,7 @@ export class Tracing implements Integration {
487
500
}
488
501
489
502
// tslint:disable-next-line: completed-docs
490
- function addRequest ( parent : SpanClass , entry : { [ key : string ] : number } ) : void {
503
+ function addRequest ( parent : Span , entry : { [ key : string ] : number } ) : void {
491
504
const request = parent . startChild ( {
492
505
description : 'request' ,
493
506
op : 'browser' ,
@@ -560,7 +573,7 @@ export class Tracing implements Integration {
560
573
if ( entry . initiatorType === 'xmlhttprequest' || entry . initiatorType === 'fetch' ) {
561
574
// We need to update existing spans with new timing info
562
575
if ( transactionSpan . spanRecorder ) {
563
- transactionSpan . spanRecorder . spans . map ( ( finishedSpan : SpanClass ) => {
576
+ transactionSpan . spanRecorder . spans . map ( ( finishedSpan : Span ) => {
564
577
if ( finishedSpan . description && finishedSpan . description . indexOf ( resourceName ) !== - 1 ) {
565
578
finishedSpan . startTimestamp = timeOrigin + startTime ;
566
579
finishedSpan . endTimestamp = finishedSpan . startTimestamp + duration ;
@@ -669,9 +682,6 @@ export class Tracing implements Integration {
669
682
return 0 ;
670
683
}
671
684
672
- // We want to clear the timeout also here since we push a new activity
673
- clearTimeout ( Tracing . _debounce ) ;
674
-
675
685
const _getCurrentHub = Tracing . _getCurrentHub ;
676
686
if ( spanContext && _getCurrentHub ) {
677
687
const hub = _getCurrentHub ( ) ;
@@ -740,16 +750,16 @@ export class Tracing implements Integration {
740
750
}
741
751
742
752
const count = Object . keys ( Tracing . _activities ) . length ;
743
- clearTimeout ( Tracing . _debounce ) ;
744
753
745
754
Tracing . _log ( '[Tracing] activies count' , count ) ;
746
755
747
756
if ( count === 0 && Tracing . _activeTransaction ) {
748
757
const timeout = Tracing . options && Tracing . options . idleTimeout ;
749
758
Tracing . _log ( `[Tracing] Flushing Transaction in ${ timeout } ms` ) ;
750
- Tracing . _debounce = ( setTimeout ( ( ) => {
759
+ Tracing . _idleTransactionEndTimestamp = timestampWithMs ( ) ;
760
+ setTimeout ( ( ) => {
751
761
Tracing . finishIdleTransaction ( ) ;
752
- } , timeout ) as any ) as number ;
762
+ } , timeout ) ;
753
763
}
754
764
}
755
765
}
0 commit comments