@@ -69,6 +69,9 @@ export class IdleTransaction extends Transaction {
6969 // We should not use heartbeat if we finished a transaction
7070 private _finished : boolean = false ;
7171
72+ // Idle timeout was canceled and we should finish the transaction with the last span end.
73+ private _idleTimeoutCanceledPermanently : boolean = false ;
74+
7275 private readonly _beforeFinishCallbacks : BeforeFinishCallback [ ] = [ ] ;
7376
7477 /**
@@ -104,7 +107,7 @@ export class IdleTransaction extends Transaction {
104107 _idleHub . configureScope ( scope => scope . setSpan ( this ) ) ;
105108 }
106109
107- this . _startIdleTimeout ( ) ;
110+ this . _restartIdleTimeout ( ) ;
108111 setTimeout ( ( ) => {
109112 if ( ! this . _finished ) {
110113 this . setStatus ( 'deadline_exceeded' ) ;
@@ -203,20 +206,37 @@ export class IdleTransaction extends Transaction {
203206 }
204207
205208 /**
206- * Cancels the existing idletimeout, if there is one
209+ * Cancels the existing idle timeout, if there is one.
210+ * @param restartOnChildSpanChange Default is `true`.
211+ * If set to false the transaction will end
212+ * with the last child span.
207213 */
208- private _cancelIdleTimeout ( ) : void {
214+ public cancelIdleTimeout (
215+ endTimestamp ?: Parameters < IdleTransaction [ 'finish' ] > [ 0 ] ,
216+ {
217+ restartOnChildSpanChange,
218+ } : {
219+ restartOnChildSpanChange ?: boolean ;
220+ } = {
221+ restartOnChildSpanChange : true ,
222+ } ,
223+ ) : void {
209224 if ( this . _idleTimeoutID ) {
210225 clearTimeout ( this . _idleTimeoutID ) ;
211226 this . _idleTimeoutID = undefined ;
227+ this . _idleTimeoutCanceledPermanently = restartOnChildSpanChange === false ;
228+
229+ if ( Object . keys ( this . activities ) . length === 0 && this . _idleTimeoutCanceledPermanently ) {
230+ this . finish ( endTimestamp ) ;
231+ }
212232 }
213233 }
214234
215235 /**
216- * Creates an idletimeout
236+ * Restarts idle timeout, if there is no running idle timeout it will start one.
217237 */
218- private _startIdleTimeout ( endTimestamp ?: Parameters < IdleTransaction [ 'finish' ] > [ 0 ] ) : void {
219- this . _cancelIdleTimeout ( ) ;
238+ private _restartIdleTimeout ( endTimestamp ?: Parameters < IdleTransaction [ 'finish' ] > [ 0 ] ) : void {
239+ this . cancelIdleTimeout ( ) ;
220240 this . _idleTimeoutID = setTimeout ( ( ) => {
221241 if ( ! this . _finished && Object . keys ( this . activities ) . length === 0 ) {
222242 this . finish ( endTimestamp ) ;
@@ -229,7 +249,7 @@ export class IdleTransaction extends Transaction {
229249 * @param spanId The span id that represents the activity
230250 */
231251 private _pushActivity ( spanId : string ) : void {
232- this . _cancelIdleTimeout ( ) ;
252+ this . cancelIdleTimeout ( ) ;
233253 __DEBUG_BUILD__ && logger . log ( `[Tracing] pushActivity: ${ spanId } ` ) ;
234254 this . activities [ spanId ] = true ;
235255 __DEBUG_BUILD__ && logger . log ( '[Tracing] new activities count' , Object . keys ( this . activities ) . length ) ;
@@ -248,10 +268,14 @@ export class IdleTransaction extends Transaction {
248268 }
249269
250270 if ( Object . keys ( this . activities ) . length === 0 ) {
251- // We need to add the timeout here to have the real endtimestamp of the transaction
252- // Remember timestampWithMs is in seconds, timeout is in ms
253- const endTimestamp = timestampWithMs ( ) + this . _idleTimeout / 1000 ;
254- this . _startIdleTimeout ( endTimestamp ) ;
271+ const endTimestamp = timestampWithMs ( ) ;
272+ if ( this . _idleTimeoutCanceledPermanently ) {
273+ this . finish ( endTimestamp ) ;
274+ } else {
275+ // We need to add the timeout here to have the real endtimestamp of the transaction
276+ // Remember timestampWithMs is in seconds, timeout is in ms
277+ this . _restartIdleTimeout ( endTimestamp + this . _idleTimeout / 1000 ) ;
278+ }
255279 }
256280 }
257281
0 commit comments