From 76bde18630389834b77e2ac646b7115b3d17be6d Mon Sep 17 00:00:00 2001 From: XAN9x Date: Tue, 3 Nov 2026 01:08:38 +0800 Subject: [PATCH 1/3] perf: reduce allocations in ConfigureScope callbacks --- src/Sentry.AspNet/HttpContextExtensions.cs | 2 +- .../Internal/BlazorWasmOptionsSetup.cs | 10 ++++---- .../SentryGrpcInterceptor.cs | 24 +++++++++---------- .../MauiCommunityToolkitMvvmEventsBinder.cs | 2 +- .../GlobalRootScopeIntegration.cs | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Sentry.AspNet/HttpContextExtensions.cs b/src/Sentry.AspNet/HttpContextExtensions.cs index 6ebadd582c..d53a4cba01 100644 --- a/src/Sentry.AspNet/HttpContextExtensions.cs +++ b/src/Sentry.AspNet/HttpContextExtensions.cs @@ -120,7 +120,7 @@ public static ITransactionTracer StartSentryTransaction(this HttpContext httpCon var transaction = SentrySdk.StartTransaction(transactionContext, customSamplingContext, dynamicSamplingContext); transaction.Contexts.Trace.Origin = AspNetOrigin; - SentrySdk.ConfigureScope(scope => scope.Transaction = transaction); + SentrySdk.ConfigureScope(static (scope, transaction) => scope.Transaction = transaction, transaction); httpContext.Items[HttpContextTransactionItemName] = transaction; if (options?.SendDefaultPii is true) diff --git a/src/Sentry.AspNetCore.Blazor.WebAssembly/Internal/BlazorWasmOptionsSetup.cs b/src/Sentry.AspNetCore.Blazor.WebAssembly/Internal/BlazorWasmOptionsSetup.cs index e284e81836..e4c3739fb5 100644 --- a/src/Sentry.AspNetCore.Blazor.WebAssembly/Internal/BlazorWasmOptionsSetup.cs +++ b/src/Sentry.AspNetCore.Blazor.WebAssembly/Internal/BlazorWasmOptionsSetup.cs @@ -35,10 +35,10 @@ public void Configure(SentryBlazorOptions options) var previousUrl = _navigationManager.Uri; // Set the initial scope request URL - _hub.ConfigureScope(scope => + _hub.ConfigureScope(static (scope, state) => { - scope.Request.Url = ToRelativePath(previousUrl); - }); + scope.Request.Url = state.Setup.ToRelativePath(state.Url); + }, (Setup: this, Url: previousUrl)); _navigationManager.LocationChanged += (_, args) => { @@ -61,10 +61,10 @@ public void Configure(SentryBlazorOptions options) { "to", to } })); - _hub.ConfigureScope(scope => + _hub.ConfigureScope(static (scope, to) => { scope.Request.Url = to; - }); + }, to); previousUrl = args.Location; }; diff --git a/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs b/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs index c08fd6ccfc..d959999380 100644 --- a/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs +++ b/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs @@ -59,10 +59,10 @@ public override async Task UnaryServerHandler( using (hub.PushAndLockScope()) { - hub.ConfigureScope(scope => + hub.ConfigureScope(static (scope, state) => { - scope.OnEvaluating += (_, activeScope) => activeScope.Populate(context, request, _options); - }); + scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, state.Request, state.Setup._options); + }, (Setup: this, Context: context, Request: request)); try { @@ -102,10 +102,10 @@ public override async Task ServerStreamingServerHandler(TRe using (hub.PushAndLockScope()) { - hub.ConfigureScope(scope => + hub.ConfigureScope(static (scope, state) => { - scope.OnEvaluating += (_, activeScope) => activeScope.Populate(context, request, _options); - }); + scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, state.Request, state.Setup._options); + }, (Setup: this, Context: context, Request: request)); try { @@ -140,10 +140,10 @@ public override async Task ClientStreamingServerHandler + hub.ConfigureScope(static (scope, state) => { - scope.OnEvaluating += (_, activeScope) => activeScope.Populate(context, null, _options); - }); + scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, null, state.Setup._options); + }, (Setup: this, Context: context)); try { @@ -183,10 +183,10 @@ public override async Task DuplexStreamingServerHandler( using (hub.PushAndLockScope()) { - hub.ConfigureScope(scope => + hub.ConfigureScope(static (scope, state) => { - scope.OnEvaluating += (_, activeScope) => activeScope.Populate(context, null, _options); - }); + scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, null, state.Setup._options); + }, (Setup: this, Context: context)); try { diff --git a/src/Sentry.Maui.CommunityToolkit.Mvvm/MauiCommunityToolkitMvvmEventsBinder.cs b/src/Sentry.Maui.CommunityToolkit.Mvvm/MauiCommunityToolkitMvvmEventsBinder.cs index 39c8a76f0e..c553ca1152 100644 --- a/src/Sentry.Maui.CommunityToolkit.Mvvm/MauiCommunityToolkitMvvmEventsBinder.cs +++ b/src/Sentry.Maui.CommunityToolkit.Mvvm/MauiCommunityToolkitMvvmEventsBinder.cs @@ -149,7 +149,7 @@ private void RelayCommandOnPropertyChanged(object? sender, PropertyChangedEventA var span = hub.StartSpan(SpanName, SpanOp); if (span is ITransactionTracer transaction) { - hub.ConfigureScope(scope => scope.Transaction = transaction); + hub.ConfigureScope(static (scope, transaction) => scope.Transaction = transaction, transaction); } relay.SetFused(span); diff --git a/src/Sentry/Integrations/GlobalRootScopeIntegration.cs b/src/Sentry/Integrations/GlobalRootScopeIntegration.cs index 0a5a47c77f..b8e03cbb3b 100644 --- a/src/Sentry/Integrations/GlobalRootScopeIntegration.cs +++ b/src/Sentry/Integrations/GlobalRootScopeIntegration.cs @@ -9,6 +9,6 @@ public void Register(IHub hub, SentryOptions options) return; } - hub.ConfigureScope(scope => scope.User.Id ??= options.InstallationId); + hub.ConfigureScope(static (scope, options) => scope.User.Id ??= options.InstallationId, options); } } From e500d47513620a3a45d928db8d7010879238458e Mon Sep 17 00:00:00 2001 From: XAN9x Date: Tue, 3 Nov 2026 12:59:46 +0800 Subject: [PATCH 2/3] refactor: simplify state passed to ConfigureScope callbacks --- .../Internal/BlazorWasmOptionsSetup.cs | 5 +---- .../SentryGrpcInterceptor.cs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Sentry.AspNetCore.Blazor.WebAssembly/Internal/BlazorWasmOptionsSetup.cs b/src/Sentry.AspNetCore.Blazor.WebAssembly/Internal/BlazorWasmOptionsSetup.cs index e4c3739fb5..fa603f300e 100644 --- a/src/Sentry.AspNetCore.Blazor.WebAssembly/Internal/BlazorWasmOptionsSetup.cs +++ b/src/Sentry.AspNetCore.Blazor.WebAssembly/Internal/BlazorWasmOptionsSetup.cs @@ -35,10 +35,7 @@ public void Configure(SentryBlazorOptions options) var previousUrl = _navigationManager.Uri; // Set the initial scope request URL - _hub.ConfigureScope(static (scope, state) => - { - scope.Request.Url = state.Setup.ToRelativePath(state.Url); - }, (Setup: this, Url: previousUrl)); + _hub.ConfigureScope(static (scope, url) => scope.Request.Url = url, ToRelativePath(previousUrl)); _navigationManager.LocationChanged += (_, args) => { diff --git a/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs b/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs index d959999380..9978f1c850 100644 --- a/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs +++ b/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs @@ -61,8 +61,8 @@ public override async Task UnaryServerHandler( { hub.ConfigureScope(static (scope, state) => { - scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, state.Request, state.Setup._options); - }, (Setup: this, Context: context, Request: request)); + scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, state.Request, state.Options); + }, (Options: _options, Context: context, Request: request)); try { @@ -104,8 +104,8 @@ public override async Task ServerStreamingServerHandler(TRe { hub.ConfigureScope(static (scope, state) => { - scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, state.Request, state.Setup._options); - }, (Setup: this, Context: context, Request: request)); + scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, state.Request, state.Options); + }, (Options: _options, Context: context, Request: request)); try { @@ -142,8 +142,8 @@ public override async Task ClientStreamingServerHandler { - scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, null, state.Setup._options); - }, (Setup: this, Context: context)); + scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, null, state.Options); + }, (Options: _options, Context: context)); try { @@ -185,8 +185,8 @@ public override async Task DuplexStreamingServerHandler( { hub.ConfigureScope(static (scope, state) => { - scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, null, state.Setup._options); - }, (Setup: this, Context: context)); + scope.OnEvaluating += (_, activeScope) => activeScope.Populate(state.Context, null, state.Options); + }, (Options: _options, Context: context)); try { From f26490369e9f3fb38a5b1a4b0c9402c06d89f297 Mon Sep 17 00:00:00 2001 From: XAN9x Date: Tue, 3 Nov 2026 17:54:37 +0800 Subject: [PATCH 3/3] test: update ConfigureScope assertions for state overload --- .../Integrations/GlobalRootScopeIntegrationTests.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/Sentry.Tests/Integrations/GlobalRootScopeIntegrationTests.cs b/test/Sentry.Tests/Integrations/GlobalRootScopeIntegrationTests.cs index 281867172a..950230adf8 100644 --- a/test/Sentry.Tests/Integrations/GlobalRootScopeIntegrationTests.cs +++ b/test/Sentry.Tests/Integrations/GlobalRootScopeIntegrationTests.cs @@ -24,7 +24,9 @@ public void Register_GlobalModeDisabled_DoesNotConfigureScope() integration.Register(hub, options); // Assert - hub.DidNotReceive().ConfigureScope(Arg.Any>()); + hub.DidNotReceive().ConfigureScope( + Arg.Any>(), + Arg.Any()); scope.User.Id.Should().BeNull(); } @@ -48,7 +50,9 @@ public void Register_GlobalModeEnabled_SetsInstallationIdOnRootScope() integration.Register(hub, options); // Assert - hub.Received(1).ConfigureScope(Arg.Any>()); + hub.Received(1).ConfigureScope( + Arg.Any>(), + Arg.Any()); scope.User.Id.Should().Be(options.InstallationId); } @@ -79,7 +83,9 @@ public void Register_GlobalModeEnabled_DoesNotOverwriteExistingUserId() integration.Register(hub, options); // Assert - hub.Received(1).ConfigureScope(Arg.Any>()); + hub.Received(1).ConfigureScope( + Arg.Any>(), + Arg.Any()); scope.User.Id.Should().Be(oldId); }