Refactor job sorting logic, reduce poll interval, and implement SignalR subscriptions for real-time updates in DataInbox and Layers pages
All checks were successful
Build Docker Images / test (map[name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Successful in 1m28s
Build Docker Images / test (map[name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Successful in 1m26s
Build Docker Images / build-and-push (map[image_suffix:morska name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Successful in 1m38s
Build Docker Images / build-and-push (map[image_suffix:pedrollopl name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Successful in 1m38s
All checks were successful
Build Docker Images / test (map[name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Successful in 1m28s
Build Docker Images / test (map[name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Successful in 1m26s
Build Docker Images / build-and-push (map[image_suffix:morska name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Successful in 1m38s
Build Docker Images / build-and-push (map[image_suffix:pedrollopl name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Successful in 1m38s
This commit is contained in:
@@ -71,11 +71,10 @@ public class JobsController : Controller
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
// Sort by: Priority ASC (0=highest), JobType, then CreatedAt DESC
|
||||
// Sort by: CreatedAt DESC (newest first), then Priority ASC (0=highest)
|
||||
var items = await query
|
||||
.OrderBy(j => j.Priority)
|
||||
.ThenBy(j => j.JobType)
|
||||
.ThenByDescending(j => j.CreatedAt)
|
||||
.OrderByDescending(j => j.CreatedAt)
|
||||
.ThenBy(j => j.Priority)
|
||||
.Skip(start)
|
||||
.Take(limit)
|
||||
.AsNoTracking()
|
||||
|
||||
@@ -11,7 +11,7 @@ public class JobWorkerService : BackgroundService
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ILogger<JobWorkerService> _logger;
|
||||
private readonly TimeSpan _pollInterval = TimeSpan.FromSeconds(10);
|
||||
private readonly TimeSpan _pollInterval = TimeSpan.FromSeconds(5);
|
||||
private readonly TimeSpan _rateLimitDelay = TimeSpan.FromSeconds(5);
|
||||
|
||||
public JobWorkerService(IServiceProvider serviceProvider, ILogger<JobWorkerService> logger)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@page "/datainbox"
|
||||
@using MudBlazor.Internal
|
||||
@using DiunaBI.Application.DTOModels
|
||||
@implements IDisposable
|
||||
|
||||
<PageTitle>Data Inbox</PageTitle>
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ using Microsoft.JSInterop;
|
||||
|
||||
namespace DiunaBI.UI.Shared.Pages.DataInbox;
|
||||
|
||||
public partial class Index : ComponentBase
|
||||
public partial class Index : ComponentBase, IDisposable
|
||||
{
|
||||
[Inject] private DataInboxService DataInboxService { get; set; } = default!;
|
||||
[Inject] private EntityChangeHubService HubService { get; set; } = default!;
|
||||
[Inject] private ISnackbar Snackbar { get; set; } = default!;
|
||||
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
|
||||
[Inject] private DataInboxFilterStateService FilterStateService { get; set; } = default!;
|
||||
@@ -27,6 +28,22 @@ public partial class Index : ComponentBase
|
||||
await DateTimeHelper.InitializeAsync();
|
||||
filterRequest = FilterStateService.FilterRequest;
|
||||
await LoadDataInbox();
|
||||
|
||||
// Subscribe to SignalR entity changes
|
||||
HubService.EntityChanged += OnEntityChanged;
|
||||
}
|
||||
|
||||
private async void OnEntityChanged(string module, string id, string operation)
|
||||
{
|
||||
// Only react if it's a DataInbox change
|
||||
if (module.Equals("DataInbox", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await InvokeAsync(async () =>
|
||||
{
|
||||
await LoadDataInbox();
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadDataInbox()
|
||||
@@ -77,4 +94,9 @@ public partial class Index : ComponentBase
|
||||
var url = NavigationManager.ToAbsoluteUri($"/datainbox/{dataInboxItem.Id}").ToString();
|
||||
await JSRuntime.InvokeVoidAsync("open", url, "_blank");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
HubService.EntityChanged -= OnEntityChanged;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,11 +69,6 @@
|
||||
</MudMenuItem>
|
||||
</MudMenu>
|
||||
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Refresh"
|
||||
OnClick="LoadJobs"
|
||||
Color="Color.Primary"
|
||||
Size="Size.Medium"
|
||||
Title="Refresh"/>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Clear"
|
||||
OnClick="ClearFilters"
|
||||
Color="Color.Default"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
@using DiunaBI.UI.Shared.Services
|
||||
@using DiunaBI.Application.DTOModels
|
||||
@using MudBlazor
|
||||
@implements IDisposable
|
||||
|
||||
<MudCard>
|
||||
<MudCardHeader>
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Reflection;
|
||||
|
||||
namespace DiunaBI.UI.Shared.Pages.Layers;
|
||||
|
||||
public partial class Details : ComponentBase
|
||||
public partial class Details : ComponentBase, IDisposable
|
||||
{
|
||||
[Parameter]
|
||||
public Guid Id { get; set; }
|
||||
@@ -20,6 +20,9 @@ public partial class Details : ComponentBase
|
||||
[Inject]
|
||||
private JobService JobService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
private EntityChangeHubService HubService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
private NavigationManager NavigationManager { get; set; } = null!;
|
||||
|
||||
@@ -57,6 +60,39 @@ public partial class Details : ComponentBase
|
||||
{
|
||||
await DateTimeHelper.InitializeAsync();
|
||||
await LoadLayer();
|
||||
|
||||
// Subscribe to SignalR entity changes
|
||||
HubService.EntityChanged += OnEntityChanged;
|
||||
}
|
||||
|
||||
private async void OnEntityChanged(string module, string id, string operation)
|
||||
{
|
||||
// React to Layers or Records changes for this layer
|
||||
if (module.Equals("Layers", StringComparison.OrdinalIgnoreCase) ||
|
||||
module.Equals("Records", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Check if it's this layer or its records that changed
|
||||
if (Guid.TryParse(id, out var changedId))
|
||||
{
|
||||
if (module.Equals("Layers", StringComparison.OrdinalIgnoreCase) && changedId == Id)
|
||||
{
|
||||
await InvokeAsync(async () =>
|
||||
{
|
||||
await LoadLayer();
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
else if (module.Equals("Records", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// For records, we reload to get the latest data
|
||||
await InvokeAsync(async () =>
|
||||
{
|
||||
await LoadLayer();
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
@@ -495,4 +531,9 @@ public partial class Details : ComponentBase
|
||||
isRunningJob = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
HubService.EntityChanged -= OnEntityChanged;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@page "/layers"
|
||||
@using MudBlazor.Internal
|
||||
@using DiunaBI.Application.DTOModels
|
||||
@implements IDisposable
|
||||
|
||||
<PageTitle>Layers</PageTitle>
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ using Microsoft.JSInterop;
|
||||
|
||||
namespace DiunaBI.UI.Shared.Pages.Layers;
|
||||
|
||||
public partial class Index : ComponentBase
|
||||
public partial class Index : ComponentBase, IDisposable
|
||||
{
|
||||
[Inject] private LayerService LayerService { get; set; } = default!;
|
||||
[Inject] private EntityChangeHubService HubService { get; set; } = default!;
|
||||
[Inject] private ISnackbar Snackbar { get; set; } = default!;
|
||||
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
|
||||
[Inject] private LayerFilterStateService FilterStateService { get; set; } = default!;
|
||||
@@ -25,6 +26,22 @@ public partial class Index : ComponentBase
|
||||
{
|
||||
filterRequest = FilterStateService.FilterRequest;
|
||||
await LoadLayers();
|
||||
|
||||
// Subscribe to SignalR entity changes
|
||||
HubService.EntityChanged += OnEntityChanged;
|
||||
}
|
||||
|
||||
private async void OnEntityChanged(string module, string id, string operation)
|
||||
{
|
||||
// Only react if it's a Layers change
|
||||
if (module.Equals("Layers", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await InvokeAsync(async () =>
|
||||
{
|
||||
await LoadLayers();
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadLayers()
|
||||
@@ -89,4 +106,9 @@ public partial class Index : ComponentBase
|
||||
var url = NavigationManager.ToAbsoluteUri($"/layers/{layer.Id}").ToString();
|
||||
await JSRuntime.InvokeVoidAsync("open", url, "_blank");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
HubService.EntityChanged -= OnEntityChanged;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user