d49330e697
Add comprehensive XML documentation (param/returns tags) across 132 source files to improve IntelliSense and API discoverability. Include ConfigManager design documents and implementation plans for phases 1-9.
81 lines
2.9 KiB
C#
81 lines
2.9 KiB
C#
using JdeScoping.Core.ViewModels;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace JdeScoping.Api.Hubs;
|
|
|
|
/// <summary>
|
|
/// SignalR hub for real-time status updates
|
|
/// </summary>
|
|
public class StatusHub : Hub
|
|
{
|
|
private const string StatusCacheKey = "StatusHub_CachedStatus";
|
|
|
|
private readonly IMemoryCache _cache;
|
|
private readonly ILogger<StatusHub> _logger;
|
|
private readonly TimeProvider _timeProvider;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="StatusHub"/> class.
|
|
/// </summary>
|
|
/// <param name="cache">The memory cache for caching status updates.</param>
|
|
/// <param name="logger">The logger instance.</param>
|
|
/// <param name="timeProvider">The time provider for getting current UTC time.</param>
|
|
public StatusHub(IMemoryCache cache, ILogger<StatusHub> logger, TimeProvider timeProvider)
|
|
{
|
|
_cache = cache;
|
|
_logger = logger;
|
|
_timeProvider = timeProvider;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by worker service to update status.
|
|
/// Caches the update and broadcasts to all clients.
|
|
/// </summary>
|
|
/// <param name="statusUpdate">Status update to broadcast</param>
|
|
public async Task SetStatus(StatusUpdateViewModel statusUpdate)
|
|
{
|
|
_cache.Set(StatusCacheKey, statusUpdate);
|
|
await Clients.All.SendAsync("statusUpdate", statusUpdate);
|
|
_logger.LogDebug("Status updated: {Message}", statusUpdate.Message);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by clients to get initial cached status on connection.
|
|
/// </summary>
|
|
/// <returns>The most recent status update</returns>
|
|
public StatusUpdateViewModel GetCachedStatus()
|
|
{
|
|
return _cache.GetOrCreate(StatusCacheKey, _ => new StatusUpdateViewModel
|
|
{
|
|
Message = "Unknown",
|
|
Timestamp = _timeProvider.GetUtcNow().DateTime
|
|
})!;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by controllers/services to broadcast search updates.
|
|
/// </summary>
|
|
/// <param name="searchUpdate">Search update to broadcast</param>
|
|
public async Task PublishSearchUpdate(SearchUpdateViewModel searchUpdate)
|
|
{
|
|
await Clients.All.SendAsync("searchUpdate", searchUpdate);
|
|
_logger.LogDebug("Search update published: ID={Id}, Status={Status}", searchUpdate.Id, searchUpdate.Status);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override Task OnConnectedAsync()
|
|
{
|
|
_logger.LogInformation("Client {ConnectionId} connected to StatusHub", Context.ConnectionId);
|
|
return base.OnConnectedAsync();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override Task OnDisconnectedAsync(Exception? exception)
|
|
{
|
|
_logger.LogInformation("Client {ConnectionId} disconnected from StatusHub", Context.ConnectionId);
|
|
return base.OnDisconnectedAsync(exception);
|
|
}
|
|
}
|