Skip to content

Commit

Permalink
Make some types non-generic
Browse files Browse the repository at this point in the history
Three types are made non-generic, as we no longer specialise by resource type:

- ViewModelProcessor
- ViewModelMonitor
- ResourceChange
  • Loading branch information
drewnoakes committed Dec 6, 2023
1 parent f2788ea commit 3069545
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 40 deletions.
5 changes: 1 addition & 4 deletions src/Aspire.Dashboard/Components/Pages/Resources.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ public partial class Resources : ComponentBase, IDisposable
private IEnumerable<EnvironmentVariableViewModel>? SelectedEnvironmentVariables { get; set; }
private string? SelectedResourceName { get; set; }

private static ViewModelMonitor<ResourceViewModel> GetViewModelMonitor(IDashboardViewModelService dashboardViewModelService)
=> dashboardViewModelService.GetResources();

private bool Filter(ResourceViewModel resource)
=> ((resource.ResourceType == "Project" && _areProjectsVisible) ||
(resource.ResourceType == "Container" && _areContainersVisible) ||
Expand Down Expand Up @@ -78,7 +75,7 @@ private void HandleTypeFilterTypeChanged()
protected override void OnInitialized()
{
_applicationUnviewedErrorCounts = TelemetryRepository.GetApplicationUnviewedErrorLogsCount();
var viewModelMonitor = GetViewModelMonitor(DashboardViewModelService);
var viewModelMonitor = DashboardViewModelService.GetResources();
var resources = viewModelMonitor.Snapshot;
var watch = viewModelMonitor.Watch;
foreach (var resource in resources)
Expand Down
7 changes: 4 additions & 3 deletions src/Aspire.Dashboard/Model/IDashboardViewModelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ public interface IDashboardViewModelService
{
string ApplicationName { get; }

ViewModelMonitor<ResourceViewModel> GetResources();
ViewModelMonitor GetResources();
}

public record ViewModelMonitor<TViewModel>(List<TViewModel> Snapshot, IAsyncEnumerable<ResourceChanged<TViewModel>> Watch)
where TViewModel : ResourceViewModel;
public record ViewModelMonitor(
List<ResourceViewModel> Snapshot,
IAsyncEnumerable<ResourceChange> Watch);
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@

namespace Aspire.Dashboard.Model;

public sealed record ResourceChanged<T>(ObjectChangeType ObjectChangeType, T Resource)
where T : class;
public sealed record ResourceChange(ObjectChangeType ObjectChangeType, ResourceViewModel Resource);
17 changes: 9 additions & 8 deletions src/Aspire.Hosting/Dashboard/DashboardViewModelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ internal sealed partial class DashboardViewModelService : IDashboardViewModelSer
private readonly CancellationTokenSource _cancellationTokenSource = new();
private readonly CancellationToken _cancellationToken;

// Private channels, for decoupling producer/consumer and serialising updates.
private readonly Channel<(WatchEventType, string, CustomResource?)> _kubernetesChangesChannel;
private readonly Channel<ResourceChange> _resourceViewModelChangesChannel;

private readonly Dictionary<string, Container> _containersMap = [];
private readonly Dictionary<string, Executable> _executablesMap = [];
private readonly Dictionary<string, Service> _servicesMap = [];
Expand All @@ -40,9 +43,7 @@ internal sealed partial class DashboardViewModelService : IDashboardViewModelSer
private readonly ConcurrentDictionary<string, List<EnvVar>> _additionalEnvVarsMap = [];
private readonly HashSet<string> _containersWithTaskStarted = [];

private readonly Channel<ResourceChanged<ResourceViewModel>> _resourceViewModelChangesChannel;

private readonly ViewModelProcessor<ResourceViewModel> _resourceViewModelProcessor;
private readonly ViewModelProcessor _resourceViewModelProcessor;

public DashboardViewModelService(
DistributedApplicationModel applicationModel, KubernetesService kubernetesService, IHostEnvironment hostEnvironment, ILoggerFactory loggerFactory)
Expand All @@ -52,23 +53,23 @@ public DashboardViewModelService(
_applicationName = ComputeApplicationName(hostEnvironment.ApplicationName);
_logger = loggerFactory.CreateLogger<DashboardViewModelService>();
_cancellationToken = _cancellationTokenSource.Token;

_kubernetesChangesChannel = Channel.CreateUnbounded<(WatchEventType, string, CustomResource?)>();
_resourceViewModelChangesChannel = Channel.CreateUnbounded<ResourceChange>();

RunWatchTask<Executable>();
RunWatchTask<Service>();
RunWatchTask<Endpoint>();
RunWatchTask<Container>();

_resourceViewModelChangesChannel = Channel.CreateUnbounded<ResourceChanged<ResourceViewModel>>();

Task.Run(ProcessKubernetesChanges);

_resourceViewModelProcessor = new ViewModelProcessor<ResourceViewModel>(_resourceViewModelChangesChannel, _cancellationToken);
_resourceViewModelProcessor = new ViewModelProcessor(_resourceViewModelChangesChannel, _cancellationToken);
}

public string ApplicationName => _applicationName;

public ViewModelMonitor<ResourceViewModel> GetResources() => _resourceViewModelProcessor.GetResourceMonitor();
public ViewModelMonitor GetResources() => _resourceViewModelProcessor.GetMonitor();

private void RunWatchTask<T>()
where T : CustomResource
Expand Down Expand Up @@ -290,7 +291,7 @@ private async Task ProcessServiceChange(WatchEventType watchEventType, Service s
private async Task WriteChange(ResourceViewModel resourceViewModel, ObjectChangeType changeType = ObjectChangeType.Modified)
{
await _resourceViewModelChangesChannel.Writer.WriteAsync(
new ResourceChanged<ResourceViewModel>(changeType, resourceViewModel), _cancellationToken)
new ResourceChange(changeType, resourceViewModel), _cancellationToken)
.ConfigureAwait(false);
}

Expand Down
46 changes: 23 additions & 23 deletions src/Aspire.Hosting/Dashboard/ViewModelProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,76 +6,76 @@

namespace Aspire.Hosting.Dashboard;

internal sealed class ViewModelProcessor<TViewModel>
where TViewModel : ResourceViewModel
internal sealed class ViewModelProcessor
{
private readonly object _syncLock = new();
private readonly Channel<ResourceChanged<TViewModel>> _incomingChannel;
private readonly Channel<ResourceChange> _incomingChannel;
private readonly CancellationToken _cancellationToken;
private readonly Dictionary<string, TViewModel> _snapshot = [];
private readonly List<Channel<ResourceChanged<TViewModel>>> _subscribedChannels = [];
private readonly Dictionary<string, ResourceViewModel> _snapshot = [];
private readonly List<Channel<ResourceChange>> _subscribedChannels = [];

public ViewModelProcessor(Channel<ResourceChanged<TViewModel>> incomingChannel, CancellationToken cancellationToken)
public ViewModelProcessor(Channel<ResourceChange> incomingChannel, CancellationToken cancellationToken)
{
_incomingChannel = incomingChannel;
_cancellationToken = cancellationToken;

Task.Run(ProcessChanges, cancellationToken);
}

public ViewModelMonitor<TViewModel> GetResourceMonitor()
public ViewModelMonitor GetMonitor()
{
lock (_syncLock)
{
var snapshot = _snapshot.Values.ToList();
var channel = Channel.CreateUnbounded<ResourceChanged<TViewModel>>();
var channel = Channel.CreateUnbounded<ResourceChange>();
_subscribedChannels.Add(channel);
var enumerable = new ChangeEnumerable(channel, RemoveChannel);

return new ViewModelMonitor<TViewModel>(snapshot, enumerable);
return new ViewModelMonitor(
Snapshot: _snapshot.Values.ToList(),
Watch: new ChangeEnumerable(channel, RemoveChannel));
}
}

private void RemoveChannel(Channel<ResourceChanged<TViewModel>> channel)
private void RemoveChannel(Channel<ResourceChange> channel)
{
lock (_syncLock)
{
_subscribedChannels.Remove(channel);
}
}

private sealed class ChangeEnumerable : IAsyncEnumerable<ResourceChanged<TViewModel>>
private sealed class ChangeEnumerable : IAsyncEnumerable<ResourceChange>
{
private readonly Channel<ResourceChanged<TViewModel>> _channel;
private readonly Action<Channel<ResourceChanged<TViewModel>>> _disposeAction;
private readonly Channel<ResourceChange> _channel;
private readonly Action<Channel<ResourceChange>> _disposeAction;

public ChangeEnumerable(Channel<ResourceChanged<TViewModel>> channel, Action<Channel<ResourceChanged<TViewModel>>> disposeAction)
public ChangeEnumerable(Channel<ResourceChange> channel, Action<Channel<ResourceChange>> disposeAction)
{
_channel = channel;
_disposeAction = disposeAction;
}

public IAsyncEnumerator<ResourceChanged<TViewModel>> GetAsyncEnumerator(CancellationToken cancellationToken = default)
public IAsyncEnumerator<ResourceChange> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new ChangeEnumerator(_channel, _disposeAction, cancellationToken);
}
}

private sealed class ChangeEnumerator : IAsyncEnumerator<ResourceChanged<TViewModel>>
private sealed class ChangeEnumerator : IAsyncEnumerator<ResourceChange>
{
private readonly Channel<ResourceChanged<TViewModel>> _channel;
private readonly Action<Channel<ResourceChanged<TViewModel>>> _disposeAction;
private readonly Channel<ResourceChange> _channel;
private readonly Action<Channel<ResourceChange>> _disposeAction;
private readonly CancellationToken _cancellationToken;

public ChangeEnumerator(
Channel<ResourceChanged<TViewModel>> channel, Action<Channel<ResourceChanged<TViewModel>>> disposeAction, CancellationToken cancellationToken)
Channel<ResourceChange> channel, Action<Channel<ResourceChange>> disposeAction, CancellationToken cancellationToken)
{
_channel = channel;
_disposeAction = disposeAction;
_cancellationToken = cancellationToken;
Current = default!;
}

public ResourceChanged<TViewModel> Current { get; private set; }
public ResourceChange Current { get; private set; }

public ValueTask DisposeAsync()
{
Expand All @@ -96,7 +96,7 @@ private async Task ProcessChanges()
{
await foreach (var change in _incomingChannel.Reader.ReadAllAsync(_cancellationToken))
{
List<Channel<ResourceChanged<TViewModel>>> outgoingChannels;
List<Channel<ResourceChange>> outgoingChannels;
lock (_syncLock)
{
var resource = change.Resource;
Expand Down

0 comments on commit 3069545

Please sign in to comment.