Skip to content

Add overload to prevent delegate allocation for ConfigureScope #4228

Closed

Description

@KnapSac

Problem Statement

I use the following code to configure a scope, capturing a value to be set as a tag on the scope. Unfortunately, this always results in a delegate allocation because of the capture.

string tagValue = "value";
SentrySdk.ConfigureScope(scope => scope.SetTag("tag_name", tagValue));

Solution Brainstorm

Perhaps there already is a better way to set a tag on the current scope, but otherwise I'd propose adding the following methods:

public static partial class SentrySdk
{
+    public static void ConfigureScope<TArg>(Action<Scope, TArg> configureScope, TArg arg);
+    public static Task ConfigureScopeAsync<TArg>(Func<Scope, TArg, Task> configureScope, TArg arg);
}

These methods could then be used like this:

string tagValue = "value";
SentrySdk.ConfigureScope(
    static (scope, arg) => scope.SetTag("tag_name", arg),
    tagValue);

I'd be happy to provide the implementation if this is something you're interested in.

Activity

  1. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on May 28, 2025
  2. jamescrosswell commented on May 28, 2025

    @jamescrosswell
    Collaborator

    @bruno-garcia maybe you've got some context around this.

    In the Hub we have this internally:

    private Scope CurrentScope => ScopeManager.GetCurrent().Key;

    Why is it we only expose that via a ConfigureScope callback (instead of surfacing it directly via the IHub interface or some public extension method)?

  3. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on May 28, 2025
  4. bruno-garcia commented on May 28, 2025

    @bruno-garcia
    Member

    @bruno-garcia maybe you've got some context around this.

    In the Hub we have this internally:

    sentry-dotnet/src/Sentry/Internal/Hub.cs

    Line 34 in 34d8490

    private Scope CurrentScope => ScopeManager.GetCurrent().Key;
    Why is it we only expose that via a ConfigureScope callback (instead of surfacing it directly via the IHub interface or some public extension method)?

    The idea is that once you return the reference explicitly you've lost ownership over it. One can hold it in a static field, access it concurrently etc. So having that state be accessed only behind our public API (SetTag, AddBreadcrumb, etc) allows us to control access, including having it be threadlocal, or asynclocal, or keep it per HTTP request (aspnet classic) etc.

  5. bruno-garcia commented on May 28, 2025

    @bruno-garcia
    Member

    We should start with adding SentrySdk.SetTag, surprised we actualy don't have that yet.

    Also not against adding overloads that allow for 0 allocations of course, but I do think we can add some stuff to our public API like SetTag and other common things.

  6. KnapSac commented on May 29, 2025

    @KnapSac
    ContributorAuthor

    That would be even better, as you wouldn't have to go through the hassle of using a callback.

    Would you be open to PRs for adding both (i.e. SentrySdk.SetTag and these 0 allocation overloads)?

  7. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on May 29, 2025
  8. bruno-garcia commented on May 29, 2025

    @bruno-garcia
    Member

    That'd be awesome. Would you start with SetTag please? Think that's slam dunk. The other one we might want to discuss further (just want to hear from @james.crosswell and @bitsandfoxes before we go ahead)

  9. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on May 29, 2025
  10. 6 remaining items

  11. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on May 30, 2025
  12. bruno-garcia commented on Jun 2, 2025

    @bruno-garcia
    Member

    That's a good point. But we cold add the overload as internal then and keep the public API simpler, in case one concern is making things confusing to users (I'm slightly concerned about that)

  13. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Jun 2, 2025
  14. KnapSac commented on Jun 2, 2025

    @KnapSac
    ContributorAuthor

    Alright, I'll throw up a PR with the overload as internal. Should consumption of the new overload be a separate PR, or are you fine having it in the same one?

  15. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Jun 2, 2025
  16. bruno-garcia commented on Jun 2, 2025

    @bruno-garcia
    Member

    Alright, I'll throw up a PR with the overload as internal. Should consumption of the new overload be a separate PR, or are you fine having it in the same one?

    Internal consumption it's fine on the same PR, but your call. Might be easier to get it added first and only change a couple spots as 'examples'. Get it merged. Then 1 large full rewrite? not sure, whatever it's easier for you and reviewers

    Thanks a lot!!!

  17. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Jun 2, 2025
  18. Flash0ver commented on Jun 3, 2025

    @Flash0ver
    Contributor

    Fine for me either way, but I do have a slight preference towards "add and adopt in one big go" when it comes to public API. This way we may figure out potential problems when consuming in some corner cases before merging. To be fair, with the new overloads in question, I doubt adopting these will be anything else but straightforward.
    We could also do an initial draft-PR including the new overloads, and then branch off of that with a new PR into that draft-PR where we use the new overloads everywhere. This way we could get smaller more focused reviews, and still detect potential (admittedly unlikely) consumption issues before merging and potentially publishing.
    But I do leave it to your preference of working / reviewing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions