Skip to content

Conversation

@bitsandfoxes
Copy link
Contributor

@bitsandfoxes bitsandfoxes commented Apr 29, 2025

Problem Statement

Underlying SDKs should be able to observe changes to the transaction, so they use the same trace context.

Proposal

  1. Leverage the existing SetTrace and call it whenever a transaction gets set/unset on the scope.
  2. When the transaction finishes, the trace context needs to be updated again. Since there is no active transaction, this falls back to the propagation context. To preserve some sort of "time continuity", and not have new events contain a trace ID that is "older" than the transaction that just finished, the propagation context gets regenerated.

@github-actions
Copy link
Contributor

github-actions bot commented Apr 29, 2025

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 7365c5a

if (ReferenceEquals(_transaction.Value, expectedCurrentTransaction))
{
_transaction.Value = null;
if (Options.EnableScopeSync)
Copy link
Contributor Author

@bitsandfoxes bitsandfoxes Apr 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, this could also look like this

internal void ResetTransaction(ITransactionTracer? expectedCurrentTransaction)
{
    if (ReferenceEquals(Transaction, expectedCurrentTransaction))
    {
        Transaction = null;
    }
}

and have the property take care of locking and synching. But I'm not fully confident in this looking at the way it's set up right originally. cc @jamescrosswell

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I wonder if we need the locking at all. It's an AsyncLocal<ITransactionTracer?> so in what scenarios would we see contention for reading/writing this? It has to be code from the same AsyncLocal context, which implicitly means it's on the same thread right? We shouldn't ever see multiple threads trying to access this concurrently?

@bruno-garcia sanity check?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's always AsyncLocal we don't need any locking

if (_transaction.Value != null)
{
// If there is a transaction set we propagate the trace to the native layer
Options.ScopeObserver?.SetTrace(_transaction.Value.TraceId, _transaction.Value.SpanId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it just the TraceId and SpanId that need to be synced? Should the sample rate and sample rand also be synced (we normally put that on the DSC to ensure consistent sampling decisions)? Or will this just be used to create spans (not transactions) and so no sampling decisions need to be made?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, they should. But both the iOS and Android ScopeObservers are missing their implementation. See #4074

It needs bumping the native SDKs to specific versions and then mess around with the bindings (especially, since the API is in private/internal parts of the Cocoa/Java SDK)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please raise a ticket in the relevant repos so we don't forget about this

@bitsandfoxes bitsandfoxes requested a review from bruno-garcia May 2, 2025 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants