Service discovery does not refresh
- Dominant language
- C#
- Stars
- 3.2k
- Forks
- 894
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 23
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
I've implemented an `IServiceEndpointProvider` that doesn't use `IChangeToken`. I would expect that `PopulateAsync` is called periodically, based on `ServiceDiscoveryOptions.RefreshPeriod`, which is documented as:
> Gets or sets the period between polling attempts for providers which do not support refresh notifications via `IChangeToken.ActiveChangeCallbacks`.
However, no refresh ever happens. The reason is because `ServiceEndpointWatcher` [never schedules the refresh timer when _any of the providers_ (so not mine) added a change token](https://github.com/dotnet/extensions/blob/0eb69ee79db77bd15df91678b36f69c73fba23a8/src/Libraries/Microsoft.Extensions.ServiceDiscovery/ServiceEndpointWatcher.cs#L158-L171):
```c#
// Check if we need to poll for updates or if we can register for change notification callbacks.
if (endpoints.ChangeToken.ActiveChangeCallbacks)
{
// Initiate a background refresh when the change token fires.
_changeTokenRegistration = endpoints.ChangeToken.RegisterChangeCallback(
static state => _ = ((ServiceEndpointWatcher)state!).RefreshAsync(force: false), this);
// Dispose the existing timer, if any, since we are reliant on change tokens for updates.
_pollingTimer?.Dispose();
_pollingTimer = null;
}
else
{
SchedulePollingTimer();
}
```
Because the configuration provider is added from `builder.Services.AddServiceDiscovery()` which is invoked from the ServiceDefaults project, there will always be a change token after `ServiceEndpointWatcher` has enumerated all providers.
Does this work as designed and is the documentation wrong, or is this a bug?
### Expected Behavior
Documented behavior to match with the implementation.
### Steps To Reproduce
- Create a new Aspire Starter project without output caching
- Implement `IServiceEndpointProviderFactory` / `IServiceEndpointProvider`
- Write a log line from `IServiceEndpointProvider.PopulateAsync`
- Add the factory to the service collection at startup, and configure `RefreshPeriod` to 1 second
- Hit the weather endpoint in the browser a few times and check the logs
### Exceptions (if any)
-
### .NET Version info
.NET 8
### Anything else?
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.