From c4fab7f11afc06de9f25902e01f33e03f0256cf1 Mon Sep 17 00:00:00 2001 From: Jared Goodwin Date: Mon, 17 May 2021 10:13:47 -0700 Subject: [PATCH] Don't update DevicesFrame on DeviceUpdated and DeviceWentOffline messages. Only update card. Add explicit Refresh button. --- Server/Components/Devices/DeviceCard.razor.cs | 21 ++++++ Server/Components/Devices/DevicesFrame.razor | 3 +- .../Components/Devices/DevicesFrame.razor.cs | 73 +++++++++---------- Tests.LoadTester/Program.cs | 20 +++-- 4 files changed, 72 insertions(+), 45 deletions(-) diff --git a/Server/Components/Devices/DeviceCard.razor.cs b/Server/Components/Devices/DeviceCard.razor.cs index 50c16e941..28f4c6e8c 100644 --- a/Server/Components/Devices/DeviceCard.razor.cs +++ b/Server/Components/Devices/DeviceCard.razor.cs @@ -64,6 +64,7 @@ public partial class DeviceCard : AuthComponentBase, IDisposable public void Dispose() { AppState.PropertyChanged -= AppState_PropertyChanged; + CircuitConnection.MessageReceived -= CircuitConnection_MessageReceived; GC.SuppressFinalize(this); } @@ -72,6 +73,7 @@ protected override async Task OnInitializedAsync() await base.OnInitializedAsync(); _theme = await AppState.GetEffectiveTheme(); AppState.PropertyChanged += AppState_PropertyChanged; + CircuitConnection.MessageReceived += CircuitConnection_MessageReceived; } private void AppState_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) @@ -84,6 +86,25 @@ private void AppState_PropertyChanged(object sender, System.ComponentModel.Prope } } + private void CircuitConnection_MessageReceived(object sender, CircuitEvent e) + { + switch (e.EventName) + { + case CircuitEventName.DeviceUpdate: + case CircuitEventName.DeviceWentOffline: + { + if (e.Params?.FirstOrDefault() is Device device && + device.ID == Device?.ID) + { + Device = device; + InvokeAsync(StateHasChanged); + } + break; + } + default: + break; + } + } private void ContextMenuOpening(MouseEventArgs args) { if (GetCardState() == DeviceCardState.Normal) diff --git a/Server/Components/Devices/DevicesFrame.razor b/Server/Components/Devices/DevicesFrame.razor index 061eb1971..95024c298 100644 --- a/Server/Components/Devices/DevicesFrame.razor +++ b/Server/Components/Devices/DevicesFrame.razor @@ -37,7 +37,8 @@
- + +
diff --git a/Server/Components/Devices/DevicesFrame.razor.cs b/Server/Components/Devices/DevicesFrame.razor.cs index 1ff8736c6..b6033594f 100644 --- a/Server/Components/Devices/DevicesFrame.razor.cs +++ b/Server/Components/Devices/DevicesFrame.razor.cs @@ -27,12 +27,12 @@ namespace Remotely.Server.Components.Devices [Authorize] public partial class DevicesFrame : AuthComponentBase, IDisposable { - private readonly object _devicesLock = new(); private readonly List _allDevices = new(); private readonly string _deviceGroupAll = Guid.NewGuid().ToString(); private readonly string _deviceGroupNone = Guid.NewGuid().ToString(); - private readonly List _devicesForPage = new(); private readonly List _deviceGroups = new(); + private readonly List _devicesForPage = new(); + private readonly object _devicesLock = new(); private readonly List _filteredDevices = new(); private readonly ConcurrentDictionary _remoteControlTargetLookup = new(); private readonly List _sortableProperties = new(); @@ -141,12 +141,6 @@ private void CircuitConnection_MessageReceived(object sender, CircuitEvent args) { switch (args.EventName) { - case CircuitEventName.DeviceUpdate: - case CircuitEventName.DeviceWentOffline: - { - Refresh(); - } - break; case CircuitEventName.DisplayMessage: { var terminalMessage = (string)args.Params[0]; @@ -190,34 +184,6 @@ private void ClearSelectedCard() AppState.DevicesFrameFocusedCardState = DeviceCardState.Normal; } - private string GetDisplayName(PropertyInfo propInfo) - { - return propInfo.GetCustomAttribute()?.Name ?? propInfo.Name; - } - - private string GetSortIcon() - { - return $"oi-sort-{_sortDirection.ToString().ToLower()}"; - } - - private void LoadDevices() - { - lock (_devicesLock) - { - _allDevices.Clear(); - - var devices = DataService.GetDevicesForUser(Username) - .OrderByDescending(x => x.IsOnline) - .ToList(); - - _allDevices.AddRange(devices); - - HighestVersion = _allDevices.Max(x => Version.TryParse(x.AgentVersion, out var result) ? result : default); - } - - FilterDevices(); - } - private void FilterDevices() { lock (_devicesLock) @@ -278,11 +244,44 @@ private void FilterDevices() .Take(_devicesPerPage); _devicesForPage.Clear(); - _devicesForPage.AddRange(devicesForPage); + _devicesForPage.AddRange(appendDevices.Concat(devicesForPage)); } } + private string GetDisplayName(PropertyInfo propInfo) + { + return propInfo.GetCustomAttribute()?.Name ?? propInfo.Name; + } + + private string GetSortIcon() + { + return $"oi-sort-{_sortDirection.ToString().ToLower()}"; + } + + private void HandleRefreshClicked() + { + Refresh(); + ToastService.ShowToast("Devices refreshed."); + } + + private void LoadDevices() + { + lock (_devicesLock) + { + _allDevices.Clear(); + + var devices = DataService.GetDevicesForUser(Username) + .OrderByDescending(x => x.IsOnline) + .ToList(); + + _allDevices.AddRange(devices); + + HighestVersion = _allDevices.Max(x => Version.TryParse(x.AgentVersion, out var result) ? result : default); + } + + FilterDevices(); + } private void PageDown() { if (_currentPage > 1) diff --git a/Tests.LoadTester/Program.cs b/Tests.LoadTester/Program.cs index 7a9e9edf4..a36e8f8b9 100644 --- a/Tests.LoadTester/Program.cs +++ b/Tests.LoadTester/Program.cs @@ -10,6 +10,7 @@ namespace Remotely.Tests.LoadTester internal class Program { private static readonly SemaphoreSlim _lock = new(10, 10); + private static readonly double _heartbeatMs = TimeSpan.FromMinutes(1).TotalMilliseconds; private static int _agentCount; private static string _organizationId; private static string _serverurl; @@ -87,14 +88,19 @@ private static async Task StartAgent(int i) return; } - var heartbeatTimer = new System.Timers.Timer(TimeSpan.FromMinutes(5).TotalMilliseconds); - heartbeatTimer.Elapsed += async (sender, args) => + + _ = Task.Run(async () => { - var currentInfo = await _deviceInfo.CreateDevice(device.ID, _organizationId); - currentInfo.DeviceName = device.DeviceName; - await hubConnection.SendAsync("DeviceHeartbeat", currentInfo); - }; - heartbeatTimer.Start(); + await Task.Delay(new Random().Next(1, (int)_heartbeatMs)); + var heartbeatTimer = new System.Timers.Timer(_heartbeatMs); + heartbeatTimer.Elapsed += async (sender, args) => + { + var currentInfo = await _deviceInfo.CreateDevice(device.ID, _organizationId); + currentInfo.DeviceName = device.DeviceName; + await hubConnection.SendAsync("DeviceHeartbeat", currentInfo); + }; + heartbeatTimer.Start(); + }); } catch (Exception ex) {