Skip to content

Fix memory leak: RuntimeConfigProvider._changeTokenRegistration never disposed#3404

Open
aaronburtle wants to merge 2 commits intomainfrom
dev/aaronburtle/fix-memory-leak-runtime-config-provider
Open

Fix memory leak: RuntimeConfigProvider._changeTokenRegistration never disposed#3404
aaronburtle wants to merge 2 commits intomainfrom
dev/aaronburtle/fix-memory-leak-runtime-config-provider

Conversation

@aaronburtle
Copy link
Copy Markdown
Contributor

@aaronburtle aaronburtle commented Mar 31, 2026

Why make this change?

Closes #3403

What is this change?

RuntimeConfigProvider has a Dispose() method that cleans up its _changeTokenRegistration (a ChangeToken.OnChange subscription), but this method was never called due to two compounding issues:

  • The class did not implement the IDisposable interface it only had a public Dispose() method. The DI container only auto-disposes services that implement IDisposable or IAsyncDisposable.

  • It was registered as a pre-created instance via services.AddSingleton(configProvider). The .NET DI container does not dispose pre-created instances; only instances it creates itself via type or factory registrations.

We also correctly register the loader in our tests using the same pattern (Loader was correctly registered in Startup).

How was this tested?

Run against our test suite.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a resource leak in the service startup/config hot-reload path by ensuring RuntimeConfigProvider’s change-token registration is properly disposed when the host/service provider is torn down.

Changes:

  • Make RuntimeConfigProvider implement IDisposable and guard against double-dispose while disposing the ChangeToken.OnChange registration.
  • Update DI registrations to use singleton factory registrations (AddSingleton<T>(sp => instance)) so the container owns and disposes the singleton.
  • Align affected test setups to use the same DI registration pattern.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Service/Startup.cs Registers RuntimeConfigProvider via factory so DI disposes it at shutdown.
src/Core/Configurations/RuntimeConfigProvider.cs Implements IDisposable and disposes _changeTokenRegistration.
src/Service.Tests/SqlTests/SqlTestBase.cs Updates test DI registration to container-owned singleton factory.
src/Service.Tests/Mcp/McpQueryTimeoutTests.cs Updates test DI registration to container-owned singleton factory.
src/Service.Tests/Mcp/EntityLevelDmlToolConfigurationTests.cs Updates test DI registration to container-owned singleton factory.
src/Service.Tests/Mcp/DescribeEntitiesFilteringTests.cs Updates test DI registration to container-owned singleton factory.
src/Service.Tests/Mcp/AggregateRecordsToolTests.cs Updates test DI registration to container-owned singleton factory.
src/Service.Tests/CosmosTests/TestBase.cs Updates test DI registrations for loader/provider to factory form for disposal.
src/Service.Tests/Authentication/JwtTokenAuthenticationUnitTests.cs Updates test DI registration to container-owned singleton factory.
src/Service.Tests/Authentication/Helpers/WebHostBuilderHelper.cs Updates test DI registrations to container-owned singleton factory.

@RubenCerna2079 RubenCerna2079 self-assigned this Apr 2, 2026
@aaronburtle aaronburtle self-assigned this Apr 2, 2026
@aaronburtle aaronburtle added 2.1 bug Something isn't working labels Apr 2, 2026
@aaronburtle aaronburtle moved this from Todo to Review In Progress in Data API builder Apr 2, 2026
@aaronburtle aaronburtle added this to the April 2026 milestone Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2.1 bug Something isn't working

Projects

Status: Review In Progress

Development

Successfully merging this pull request may close these issues.

[Bug]: RuntimeConfigProvider._changeTokenRegistration is never disposed due to missing IDisposable interface and pre-created instance registration

4 participants