Skip to content

Commit

Permalink
Refactored EventTable to reduce and speed up rendering updates
Browse files Browse the repository at this point in the history
  • Loading branch information
jschick04 authored and bill-long committed Feb 14, 2024
1 parent f11d9d7 commit 77355db
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 175 deletions.
23 changes: 17 additions & 6 deletions src/EventLogExpert.UI/Store/EventLog/EventLogEffects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
namespace EventLogExpert.UI.Store.EventLog;

public sealed class EventLogEffects(
IEventResolver eventResolver,
IState<EventLogState> eventLogState,
ILogWatcherService logWatcherService)
ILogWatcherService logWatcherService,
IServiceProvider serviceProvider)
{
[EffectMethod]
public Task HandleAddEvent(EventLogAction.AddEvent action, IDispatcher dispatcher)
Expand Down Expand Up @@ -94,6 +94,17 @@ public Task HandleLoadNewEvents(IDispatcher dispatcher)
[EffectMethod]
public async Task HandleOpenLog(EventLogAction.OpenLog action, IDispatcher dispatcher)
{
using var scopedProvider = serviceProvider.CreateScope();

var eventResolver = scopedProvider.ServiceProvider.GetService<IEventResolver>();

if (eventResolver is null)
{
dispatcher.Dispatch(new StatusBarAction.SetResolverStatus("Error: No event resolver available"));

return;
}

EventLogReader reader = action.LogType == LogType.Live ?
new EventLogReader(action.LogName, PathType.LogName) :
new EventLogReader(action.LogName, PathType.FilePath);
Expand Down Expand Up @@ -153,7 +164,6 @@ await Task.Run(() =>
eventTaskNamesAll.ToImmutableList(),
eventKeywordNamesAll.ToImmutableList()));

dispatcher.Dispatch(new EventTableAction.ToggleLoading(action.LogName));
dispatcher.Dispatch(new StatusBarAction.SetEventsLoading(activityId, 0));

if (action.LogType == LogType.Live)
Expand All @@ -179,18 +189,19 @@ await Task.Run(() =>
}
},
action.Token);

dispatcher.Dispatch(new StatusBarAction.SetXmlLoading(activityId, 0));
}
catch (TaskCanceledException)
{
dispatcher.Dispatch(new EventLogAction.CloseLog(action.LogName));
dispatcher.Dispatch(new StatusBarAction.ClearStatus(activityId));
}
finally
{
dispatcher.Dispatch(new StatusBarAction.SetXmlLoading(activityId, 0));
dispatcher.Dispatch(new StatusBarAction.SetResolverStatus(""));
dispatcher.Dispatch(new StatusBarAction.SetResolverStatus(string.Empty));

reader.Dispose();
eventResolver.Dispose();
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/EventLogExpert.UI/Store/EventTable/EventTableAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ public sealed record ToggleLoading(string LogName);

public sealed record ToggleSorting;

public sealed record UpdateCombinedEvents;

public sealed record UpdateDisplayedEvents(IDictionary<string, IEnumerable<DisplayEventModel>> ActiveLogs);
}
22 changes: 22 additions & 0 deletions src/EventLogExpert.UI/Store/EventTable/EventTableEffects.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// // Copyright (c) Microsoft Corporation.
// // Licensed under the MIT License.

using Fluxor;

namespace EventLogExpert.UI.Store.EventTable;

public sealed class EventTableEffects(IState<EventTableState> eventTableState)
{
[EffectMethod(typeof(EventTableAction.UpdateDisplayedEvents))]
public Task HandleUpdateDisplayedEvents(IDispatcher dispatcher)
{
if (eventTableState.Value.EventTables.Any(table => table.IsLoading))
{
return Task.CompletedTask;
}

dispatcher.Dispatch(new EventTableAction.UpdateCombinedEvents());

return Task.CompletedTask;
}
}
58 changes: 37 additions & 21 deletions src/EventLogExpert.UI/Store/EventTable/EventTableReducers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ public static EventTableState ReduceAddTable(EventTableState state, EventTableAc

if (combinedTable is not null)
{
return state with
{
EventTables = state.EventTables.Add(newTable),
ActiveTableId = combinedTable.Id
};
return state with { EventTables = state.EventTables.Add(newTable) };
}

combinedTable = new EventTableModel { IsCombined = true };
Expand Down Expand Up @@ -117,42 +113,62 @@ public static EventTableState ReduceToggleLoading(EventTableState state, EventTa
public static EventTableState ReduceToggleSorting(EventTableState state) =>
SortDisplayEvents(state, state.OrderBy, !state.IsDescending);

[ReducerMethod(typeof(EventTableAction.UpdateCombinedEvents))]
public static EventTableState ReduceUpdateCombinedEvents(EventTableState state)
{
if (state.EventTables.Count <= 1) { return state; }

var updatedTable = state.EventTables.First(table => table.IsCombined);

return state with
{
EventTables = state.EventTables
.Remove(updatedTable)
.Add(updatedTable with
{
DisplayedEvents = GetCombinedEvents(
state.EventTables
.Where(table => !table.IsCombined)
.Select(table => table.DisplayedEvents))
.SortEvents(state.OrderBy ?? ColumnName.DateAndTime, state.IsDescending)
.ToList()
.AsReadOnly()
})
};
}

[ReducerMethod]
public static EventTableState ReduceUpdateDisplayedEvents(EventTableState state,
public static EventTableState ReduceUpdateDisplayedEvents(
EventTableState state,
EventTableAction.UpdateDisplayedEvents action)
{
List<EventTableModel> updatedTables = [];

foreach (var table in state.EventTables)
{
if (table.IsCombined) { continue; }
if (table.IsCombined)
{
updatedTables.Add(table);

continue;
}

var currentActiveLog = action.ActiveLogs.First(log => string.Equals(table.LogName, log.Key)).Value;

updatedTables.Add(table.DisplayedEvents.Count == currentActiveLog.Count() ? table : table with
{
DisplayedEvents = currentActiveLog.SortEvents(state.OrderBy, state.IsDescending)
.ToList()
.AsReadOnly()
.AsReadOnly(),
IsLoading = false
});
}

if (updatedTables.Count > 1)
{
updatedTables.Add(
state.EventTables.First(table => table.IsCombined) with
{
DisplayedEvents = GetCombinedEvents(action.ActiveLogs.Values.Select(log => log))
.SortEvents(state.OrderBy ?? ColumnName.DateAndTime, state.IsDescending)
.ToList()
.AsReadOnly()
});
}

return state with { EventTables = [.. updatedTables] };
}

private static IEnumerable<DisplayEventModel> GetCombinedEvents(IEnumerable<IEnumerable<DisplayEventModel>> eventLists)
private static IEnumerable<DisplayEventModel> GetCombinedEvents(
IEnumerable<IEnumerable<DisplayEventModel>> eventLists)
{
List<DisplayEventModel> combinedEvents = [];

Expand Down
57 changes: 11 additions & 46 deletions src/EventLogExpert.UI/Store/LoggingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using EventLogExpert.UI.Store.FilterColor;
using EventLogExpert.UI.Store.FilterGroup;
using EventLogExpert.UI.Store.FilterPane;
using EventLogExpert.UI.Store.StatusBar;
using Fluxor;
using System.Text.Json;
using IDispatcher = Fluxor.IDispatcher;
Expand All @@ -29,68 +28,34 @@ public override void BeforeDispatch(object action)
debugLogger.Trace($"Action: {action.GetType()} with {addEventsAction.NewEvent.Source} event ID {addEventsAction.NewEvent.Id}.");

break;
case EventTableAction.AddTable :
case EventTableAction.CloseAll :
case EventTableAction.CloseLog :
case EventTableAction.SetActiveTable :
case EventTableAction.SetOrderBy :
case EventTableAction.ToggleLoading :
case EventTableAction.ToggleSorting :
case EventLogAction.OpenLog openLogAction :
debugLogger.Trace($"Action: {action.GetType()} with {openLogAction.LogName} log type {openLogAction.LogType}.");
break;
case EventLogAction.AddEventBuffered :
case EventLogAction.AddEventSuccess :
case EventLogAction.SetFilters :
case EventTableAction.UpdateDisplayedEvents :
case FilterCacheAction.AddFavoriteFilter :
case FilterCacheAction.AddFavoriteFilterCompleted :
case FilterCacheAction.AddRecentFilter :
case FilterCacheAction.AddRecentFilterCompleted :
case FilterCacheAction.RemoveFavoriteFilter :
case FilterCacheAction.RemoveFavoriteFilterCompleted :
case FilterCacheAction.ImportFavorites :
case FilterCacheAction.LoadFiltersCompleted :
case FilterColorAction.ClearAllFilters :
case FilterColorAction.RemoveFilter :
case FilterCacheAction.RemoveFavoriteFilterCompleted :
case FilterColorAction.SetFilter :
case FilterGroupAction.AddFilter :
case FilterColorAction.SetFilters :
case FilterGroupAction.AddGroup :
case FilterGroupAction.LoadGroups :
case FilterGroupAction.ImportGroups :
case FilterGroupAction.LoadGroupsSuccess :
case FilterGroupAction.OpenMenu :
case FilterGroupAction.RemoveFilter :
case FilterGroupAction.RemoveGroup :
case FilterGroupAction.SetFilter :
case FilterGroupAction.SetGroup :
case FilterGroupAction.ToggleFilter :
case FilterGroupAction.ToggleGroup :
case FilterGroupAction.UpdateDisplayGroups :
case FilterPaneAction.AddAdvancedFilter :
case FilterPaneAction.AddBasicFilter :
case FilterPaneAction.AddCachedFilter :
case FilterPaneAction.AddSubFilter :
case FilterPaneAction.ApplyFilterGroup :
case FilterPaneAction.ClearAllFilters :
case FilterPaneAction.RemoveAdvancedFilter :
case FilterPaneAction.RemoveBasicFilter :
case FilterPaneAction.RemoveCachedFilter :
case FilterPaneAction.RemoveSubFilter :
case FilterPaneAction.SaveFilterGroup :
case FilterPaneAction.SetAdvancedFilter :
case FilterPaneAction.SetBasicFilter :
case FilterPaneAction.SetCachedFilter :
case FilterPaneAction.SetFilterDateRange :
case FilterPaneAction.ToggleAdvancedFilterEditing :
case FilterPaneAction.ToggleAdvancedFilterEnabled :
case FilterPaneAction.ToggleBasicFilterEditing :
case FilterPaneAction.ToggleBasicFilterEnabled :
case FilterPaneAction.ToggleCachedFilterEditing :
case FilterPaneAction.ToggleCachedFilterEnabled :
case FilterPaneAction.ToggleFilterDate :
case FilterPaneAction.ToggleIsEnabled :
case FilterPaneAction.ToggleIsLoading :
case EventLogAction.AddEventBuffered :
case EventLogAction.AddEventSuccess :
case EventLogAction.CloseAll :
case EventLogAction.CloseLog :
case EventLogAction.LoadNewEvents :
case EventLogAction.SetContinouslyUpdate :
case EventLogAction.SetFilters :
case StatusBarAction.SetEventsLoading :
case StatusBarAction.SetXmlLoading :
debugLogger.Trace($"Action: {action.GetType()}.");
break;
case EventLogAction.SelectEvent selectEventAction :
Expand Down
2 changes: 2 additions & 0 deletions src/EventLogExpert.UI/Store/StatusBar/StatusBarAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace EventLogExpert.UI.Store.StatusBar;

public sealed record StatusBarAction
{
public sealed record ClearStatus(Guid ActivityId);

public sealed record CloseAll;

/// <summary>Used to indicate the progress of event logs being loaded.</summary>
Expand Down
18 changes: 18 additions & 0 deletions src/EventLogExpert.UI/Store/StatusBar/StatusBarReducers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@ namespace EventLogExpert.UI.Store.StatusBar;

public sealed class StatusBarReducers
{
[ReducerMethod]
public static StatusBarState ReduceCloseAll(StatusBarState state, StatusBarAction.ClearStatus action)
{
var updatedState = state with { };

if (state.EventsLoading.ContainsKey(action.ActivityId))
{
updatedState = updatedState with { EventsLoading = updatedState.EventsLoading.Remove(action.ActivityId) };
}

if (state.XmlLoading.ContainsKey(action.ActivityId))
{
updatedState = updatedState with { XmlLoading = updatedState.XmlLoading.Remove(action.ActivityId) };
}

return updatedState;
}

[ReducerMethod(typeof(StatusBarAction.CloseAll))]
public static StatusBarState ReduceCloseAll(StatusBarState state) => new();

Expand Down
1 change: 0 additions & 1 deletion src/EventLogExpert/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using EventLogExpert.Eventing.EventResolvers;
using EventLogExpert.Eventing.Helpers;
using EventLogExpert.Eventing.Models;
using EventLogExpert.Services;
using EventLogExpert.UI.Models;
using EventLogExpert.UI.Options;
Expand Down
Loading

0 comments on commit 77355db

Please sign in to comment.