{"version":3,"file":"idletransaction.js","sources":["../../../src/tracing/idletransaction.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { SpanTimeInput, TransactionContext } from '@sentry/types';\nimport { logger, timestampInSeconds } from '@sentry/utils';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Hub } from '../hub';\nimport { spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';\nimport type { Span } from './span';\nimport { SpanRecorder } from './span';\nimport { Transaction } from './transaction';\n\nexport const TRACING_DEFAULTS = {\n  idleTimeout: 1000,\n  finalTimeout: 30000,\n  heartbeatInterval: 5000,\n};\n\nconst FINISH_REASON_TAG = 'finishReason';\n\nconst IDLE_TRANSACTION_FINISH_REASONS = [\n  'heartbeatFailed',\n  'idleTimeout',\n  'documentHidden',\n  'finalTimeout',\n  'externalFinish',\n  'cancelled',\n];\n\n/**\n * @inheritDoc\n */\nexport class IdleTransactionSpanRecorder extends SpanRecorder {\n  public constructor(\n    private readonly _pushActivity: (id: string) => void,\n    private readonly _popActivity: (id: string) => void,\n    public transactionSpanId: string,\n    maxlen?: number,\n  ) {\n    super(maxlen);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public add(span: Span): void {\n    // We should make sure we do not push and pop activities for\n    // the transaction that this span recorder belongs to.\n    if (span.spanContext().spanId !== this.transactionSpanId) {\n      // We patch span.end() to pop an activity after setting an endTimestamp.\n      // eslint-disable-next-line @typescript-eslint/unbound-method\n      const originalEnd = span.end;\n      span.end = (...rest: unknown[]) => {\n        this._popActivity(span.spanContext().spanId);\n        return originalEnd.apply(span, rest);\n      };\n\n      // We should only push new activities if the span does not have an end timestamp.\n      if (spanToJSON(span).timestamp === undefined) {\n        this._pushActivity(span.spanContext().spanId);\n      }\n    }\n\n    super.add(span);\n  }\n}\n\nexport type BeforeFinishCallback = (transactionSpan: IdleTransaction, endTimestamp: number) => void;\n\n/**\n * An IdleTransaction is a transaction that automatically finishes. It does this by tracking child spans as activities.\n * You can have multiple IdleTransactions active, but if the `onScope` option is specified, the idle transaction will\n * put itself on the scope on creation.\n */\nexport class IdleTransaction extends Transaction {\n  // Activities store a list of active spans\n  public activities: Record<string, boolean>;\n  // Track state of activities in previous heartbeat\n  private _prevHeartbeatString: string | undefined;\n\n  // Amount of times heartbeat has counted. Will cause transaction to finish after 3 beats.\n  private _heartbeatCounter: number;\n\n  // We should not use heartbeat if we finished a transaction\n  private _finished: boolean;\n\n  // Idle timeout was canceled and we should finish the transaction with the last span end.\n  private _idleTimeoutCanceledPermanently: boolean;\n\n  private readonly _beforeFinishCallbacks: BeforeFinishCallback[];\n\n  /**\n   * Timer that tracks Transaction idleTimeout\n   */\n  private _idleTimeoutID: ReturnType<typeof setTimeout> | undefined;\n\n  private _finishReason: (typeof IDLE_TRANSACTION_FINISH_REASONS)[number];\n\n  private _autoFinishAllowed: boolean;\n\n  /**\n   * @deprecated Transactions will be removed in v8. Use spans instead.\n   */\n  public constructor(\n    transactionContext: TransactionContext,\n    // eslint-disable-next-line deprecation/deprecation\n    private readonly _idleHub: Hub,\n    /**\n     * The time to wait in ms until the idle transaction will be finished. This timer is started each time\n     * there are no active spans on this transaction.\n     */\n    private readonly _idleTimeout: number = TRACING_DEFAULTS.idleTimeout,\n    /**\n     * The final value in ms that a transaction cannot exceed\n     */\n    private readonly _finalTimeout: number = TRACING_DEFAULTS.finalTimeout,\n    private readonly _heartbeatInterval: number = TRACING_DEFAULTS.heartbeatInterval,\n    // Whether or not the transaction should put itself on the scope when it starts and pop itself off when it ends\n    private readonly _onScope: boolean = false,\n    /**\n     * When set to `true`, will disable the idle timeout (`_idleTimeout` option) and heartbeat mechanisms (`_heartbeatInterval`\n     * option) until the `sendAutoFinishSignal()` method is called. The final timeout mechanism (`_finalTimeout` option)\n     * will not be affected by this option, meaning the transaction will definitely be finished when the final timeout is\n     * reached, no matter what this option is configured to.\n     *\n     * Defaults to `false`.\n     */\n    delayAutoFinishUntilSignal: boolean = false,\n  ) {\n    super(transactionContext, _idleHub);\n\n    this.activities = {};\n    this._heartbeatCounter = 0;\n    this._finished = false;\n    this._idleTimeoutCanceledPermanently = false;\n    this._beforeFinishCallbacks = [];\n    this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[4];\n    this._autoFinishAllowed = !delayAutoFinishUntilSignal;\n\n    if (_onScope) {\n      // We set the transaction here on the scope so error events pick up the trace\n      // context and attach it to the error.\n      DEBUG_BUILD && logger.log(`Setting idle transaction on scope. Span ID: ${this.spanContext().spanId}`);\n      // eslint-disable-next-line deprecation/deprecation\n      _idleHub.getScope().setSpan(this);\n    }\n\n    if (!delayAutoFinishUntilSignal) {\n      this._restartIdleTimeout();\n    }\n\n    setTimeout(() => {\n      if (!this._finished) {\n        this.setStatus('deadline_exceeded');\n        this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[3];\n        this.end();\n      }\n    }, this._finalTimeout);\n  }\n\n  /** {@inheritDoc} */\n  public end(endTimestamp?: SpanTimeInput): string | undefined {\n    const endTimestampInS = spanTimeInputToSeconds(endTimestamp);\n\n    this._finished = true;\n    this.activities = {};\n\n    // eslint-disable-next-line deprecation/deprecation\n    if (this.op === 'ui.action.click') {\n      this.setAttribute(FINISH_REASON_TAG, this._finishReason);\n    }\n\n    // eslint-disable-next-line deprecation/deprecation\n    if (this.spanRecorder) {\n      DEBUG_BUILD &&\n        // eslint-disable-next-line deprecation/deprecation\n        logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestampInS * 1000).toISOString(), this.op);\n\n      for (const callback of this._beforeFinishCallbacks) {\n        callback(this, endTimestampInS);\n      }\n\n      // eslint-disable-next-line deprecation/deprecation\n      this.spanRecorder.spans = this.spanRecorder.spans.filter((span: Span) => {\n        // If we are dealing with the transaction itself, we just return it\n        if (span.spanContext().spanId === this.spanContext().spanId) {\n          return true;\n        }\n\n        // We cancel all pending spans with status \"cancelled\" to indicate the idle transaction was finished early\n        if (!spanToJSON(span).timestamp) {\n          span.setStatus('cancelled');\n          span.end(endTimestampInS);\n          DEBUG_BUILD &&\n            logger.log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2));\n        }\n\n        const { start_timestamp: startTime, timestamp: endTime } = spanToJSON(span);\n        const spanStartedBeforeTransactionFinish = startTime && startTime < endTimestampInS;\n\n        // Add a delta with idle timeout so that we prevent false positives\n        const timeoutWithMarginOfError = (this._finalTimeout + this._idleTimeout) / 1000;\n        const spanEndedBeforeFinalTimeout = endTime && startTime && endTime - startTime < timeoutWithMarginOfError;\n\n        if (DEBUG_BUILD) {\n          const stringifiedSpan = JSON.stringify(span, undefined, 2);\n          if (!spanStartedBeforeTransactionFinish) {\n            logger.log('[Tracing] discarding Span since it happened after Transaction was finished', stringifiedSpan);\n          } else if (!spanEndedBeforeFinalTimeout) {\n            logger.log('[Tracing] discarding Span since it finished after Transaction final timeout', stringifiedSpan);\n          }\n        }\n\n        return spanStartedBeforeTransactionFinish && spanEndedBeforeFinalTimeout;\n      });\n\n      DEBUG_BUILD && logger.log('[Tracing] flushing IdleTransaction');\n    } else {\n      DEBUG_BUILD && logger.log('[Tracing] No active IdleTransaction');\n    }\n\n    // if `this._onScope` is `true`, the transaction put itself on the scope when it started\n    if (this._onScope) {\n      // eslint-disable-next-line deprecation/deprecation\n      const scope = this._idleHub.getScope();\n      // eslint-disable-next-line deprecation/deprecation\n      if (scope.getTransaction() === this) {\n        // eslint-disable-next-line deprecation/deprecation\n        scope.setSpan(undefined);\n      }\n    }\n\n    return super.end(endTimestamp);\n  }\n\n  /**\n   * Register a callback function that gets executed before the transaction finishes.\n   * Useful for cleanup or if you want to add any additional spans based on current context.\n   *\n   * This is exposed because users have no other way of running something before an idle transaction\n   * finishes.\n   */\n  public registerBeforeFinishCallback(callback: BeforeFinishCallback): void {\n    this._beforeFinishCallbacks.push(callback);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public initSpanRecorder(maxlen?: number): void {\n    // eslint-disable-next-line deprecation/deprecation\n    if (!this.spanRecorder) {\n      const pushActivity = (id: string): void => {\n        if (this._finished) {\n          return;\n        }\n        this._pushActivity(id);\n      };\n      const popActivity = (id: string): void => {\n        if (this._finished) {\n          return;\n        }\n        this._popActivity(id);\n      };\n\n      // eslint-disable-next-line deprecation/deprecation\n      this.spanRecorder = new IdleTransactionSpanRecorder(pushActivity, popActivity, this.spanContext().spanId, maxlen);\n\n      // Start heartbeat so that transactions do not run forever.\n      DEBUG_BUILD && logger.log('Starting heartbeat');\n      this._pingHeartbeat();\n    }\n    // eslint-disable-next-line deprecation/deprecation\n    this.spanRecorder.add(this);\n  }\n\n  /**\n   * Cancels the existing idle timeout, if there is one.\n   * @param restartOnChildSpanChange Default is `true`.\n   *                                 If set to false the transaction will end\n   *                                 with the last child span.\n   */\n  public cancelIdleTimeout(\n    endTimestamp?: Parameters<IdleTransaction['end']>[0],\n    {\n      restartOnChildSpanChange,\n    }: {\n      restartOnChildSpanChange?: boolean;\n    } = {\n      restartOnChildSpanChange: true,\n    },\n  ): void {\n    this._idleTimeoutCanceledPermanently = restartOnChildSpanChange === false;\n    if (this._idleTimeoutID) {\n      clearTimeout(this._idleTimeoutID);\n      this._idleTimeoutID = undefined;\n\n      if (Object.keys(this.activities).length === 0 && this._idleTimeoutCanceledPermanently) {\n        this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5];\n        this.end(endTimestamp);\n      }\n    }\n  }\n\n  /**\n   * Temporary method used to externally set the transaction's `finishReason`\n   *\n   * ** WARNING**\n   * This is for the purpose of experimentation only and will be removed in the near future, do not use!\n   *\n   * @internal\n   *\n   */\n  public setFinishReason(reason: string): void {\n    this._finishReason = reason;\n  }\n\n  /**\n   * Permits the IdleTransaction to automatically end itself via the idle timeout and heartbeat mechanisms when the `delayAutoFinishUntilSignal` option was set to `true`.\n   */\n  public sendAutoFinishSignal(): void {\n    if (!this._autoFinishAllowed) {\n      DEBUG_BUILD && logger.log('[Tracing] Received finish signal for idle transaction.');\n      this._restartIdleTimeout();\n      this._autoFinishAllowed = true;\n    }\n  }\n\n  /**\n   * Restarts idle timeout, if there is no running idle timeout it will start one.\n   */\n  private _restartIdleTimeout(endTimestamp?: Parameters<IdleTransaction['end']>[0]): void {\n    this.cancelIdleTimeout();\n    this._idleTimeoutID = setTimeout(() => {\n      if (!this._finished && Object.keys(this.activities).length === 0) {\n        this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[1];\n        this.end(endTimestamp);\n      }\n    }, this._idleTimeout);\n  }\n\n  /**\n   * Start tracking a specific activity.\n   * @param spanId The span id that represents the activity\n   */\n  private _pushActivity(spanId: string): void {\n    this.cancelIdleTimeout(undefined, { restartOnChildSpanChange: !this._idleTimeoutCanceledPermanently });\n    DEBUG_BUILD && logger.log(`[Tracing] pushActivity: ${spanId}`);\n    this.activities[spanId] = true;\n    DEBUG_BUILD && logger.log('[Tracing] new activities count', Object.keys(this.activities).length);\n  }\n\n  /**\n   * Remove an activity from usage\n   * @param spanId The span id that represents the activity\n   */\n  private _popActivity(spanId: string): void {\n    if (this.activities[spanId]) {\n      DEBUG_BUILD && logger.log(`[Tracing] popActivity ${spanId}`);\n      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n      delete this.activities[spanId];\n      DEBUG_BUILD && logger.log('[Tracing] new activities count', Object.keys(this.activities).length);\n    }\n\n    if (Object.keys(this.activities).length === 0) {\n      const endTimestamp = timestampInSeconds();\n      if (this._idleTimeoutCanceledPermanently) {\n        if (this._autoFinishAllowed) {\n          this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5];\n          this.end(endTimestamp);\n        }\n      } else {\n        // We need to add the timeout here to have the real endtimestamp of the transaction\n        // Remember timestampInSeconds is in seconds, timeout is in ms\n        this._restartIdleTimeout(endTimestamp + this._idleTimeout / 1000);\n      }\n    }\n  }\n\n  /**\n   * Checks when entries of this.activities are not changing for 3 beats.\n   * If this occurs we finish the transaction.\n   */\n  private _beat(): void {\n    // We should not be running heartbeat if the idle transaction is finished.\n    if (this._finished) {\n      return;\n    }\n\n    const heartbeatString = Object.keys(this.activities).join('');\n\n    if (heartbeatString === this._prevHeartbeatString) {\n      this._heartbeatCounter++;\n    } else {\n      this._heartbeatCounter = 1;\n    }\n\n    this._prevHeartbeatString = heartbeatString;\n\n    if (this._heartbeatCounter >= 3) {\n      if (this._autoFinishAllowed) {\n        DEBUG_BUILD && logger.log('[Tracing] Transaction finished because of no change for 3 heart beats');\n        this.setStatus('deadline_exceeded');\n        this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[0];\n        this.end();\n      }\n    } else {\n      this._pingHeartbeat();\n    }\n  }\n\n  /**\n   * Pings the heartbeat\n   */\n  private _pingHeartbeat(): void {\n    DEBUG_BUILD && logger.log(`pinging Heartbeat -> current counter: ${this._heartbeatCounter}`);\n    setTimeout(() => {\n      this._beat();\n    }, this._heartbeatInterval);\n  }\n}\n"],"names":[],"mappings":"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"}