Add signalr
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using Managing.Application.Abstractions.Repositories;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.Bots;
|
||||
using Managing.Application.Hubs;
|
||||
using Managing.Core.FixedSizedQueue;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Backtests;
|
||||
@@ -13,8 +14,10 @@ using Managing.Domain.Strategies;
|
||||
using Managing.Domain.Strategies.Base;
|
||||
using Managing.Domain.Users;
|
||||
using Managing.Domain.Workflows;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static Managing.Common.Enums;
|
||||
using LightBacktestResponse = Managing.Domain.Backtests.LightBacktest; // Use the domain model for notification
|
||||
|
||||
namespace Managing.Application.Backtesting
|
||||
{
|
||||
@@ -28,6 +31,7 @@ namespace Managing.Application.Backtesting
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly IMessengerService _messengerService;
|
||||
private readonly IKaigenService _kaigenService;
|
||||
private readonly IHubContext<BacktestHub> _hubContext;
|
||||
|
||||
public Backtester(
|
||||
IExchangeService exchangeService,
|
||||
@@ -37,7 +41,8 @@ namespace Managing.Application.Backtesting
|
||||
IScenarioService scenarioService,
|
||||
IAccountService accountService,
|
||||
IMessengerService messengerService,
|
||||
IKaigenService kaigenService)
|
||||
IKaigenService kaigenService,
|
||||
IHubContext<BacktestHub> hubContext)
|
||||
{
|
||||
_exchangeService = exchangeService;
|
||||
_botFactory = botFactory;
|
||||
@@ -47,6 +52,7 @@ namespace Managing.Application.Backtesting
|
||||
_accountService = accountService;
|
||||
_messengerService = messengerService;
|
||||
_kaigenService = kaigenService;
|
||||
_hubContext = hubContext;
|
||||
}
|
||||
|
||||
public Backtest RunSimpleBotBacktest(Workflow workflow, bool save = false)
|
||||
@@ -604,5 +610,14 @@ namespace Managing.Application.Backtesting
|
||||
{
|
||||
return _backtestRepository.GetPendingBundleBacktestRequests();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a LightBacktestResponse to all SignalR subscribers of a bundle request.
|
||||
/// </summary>
|
||||
public async Task SendBundleBacktestUpdateAsync(string requestId, LightBacktestResponse response)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(requestId) || response == null) return;
|
||||
await _hubContext.Clients.Group($"bundle-{requestId}").SendAsync("BundleBacktestUpdate", response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,20 @@ namespace Managing.Application.Hubs;
|
||||
|
||||
public class BacktestHub : Hub
|
||||
{
|
||||
public async override Task OnConnectedAsync()
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
await base.OnConnectedAsync();
|
||||
await Clients.Caller.SendAsync("Message", $"Connected successfully on backtest hub. ConnectionId : {Context.ConnectionId}");
|
||||
await Clients.Caller.SendAsync("Message", "Connected to BacktestHub!");
|
||||
}
|
||||
|
||||
public async Task SubscribeBots() =>
|
||||
await Clients.All.SendAsync("BacktestsSubscription", "Successfully subscribed");
|
||||
public async Task SubscribeToBundle(string requestId)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(requestId))
|
||||
{
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, $"bundle-{requestId}");
|
||||
await Clients.Caller.SendAsync("SubscribedToBundle", requestId);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetConnectionId() => Context.ConnectionId;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.Hubs;
|
||||
using Managing.Application.Workers.Abstractions;
|
||||
using Managing.Domain.Backtests;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Application.Workers;
|
||||
|
||||
public class NotifyBundleBacktestWorker : BaseWorker<NotifyBundleBacktestWorker>
|
||||
{
|
||||
private readonly IBacktester _backtester;
|
||||
private readonly IHubContext<BacktestHub> _hubContext;
|
||||
private readonly ConcurrentDictionary<string, HashSet<string>> _sentBacktestIds = new();
|
||||
|
||||
public NotifyBundleBacktestWorker(
|
||||
IBacktester backtester,
|
||||
IHubContext<BacktestHub> hubContext,
|
||||
ILogger<NotifyBundleBacktestWorker> logger,
|
||||
IWorkerService workerService)
|
||||
: base(WorkerType.NotifyBundleBacktest, logger, TimeSpan.FromMinutes(1), workerService)
|
||||
{
|
||||
_backtester = backtester;
|
||||
_hubContext = hubContext;
|
||||
}
|
||||
|
||||
protected override async Task Run(CancellationToken stoppingToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Fetch all running bundle requests
|
||||
var runningBundles = _backtester.GetPendingBundleBacktestRequests()
|
||||
.Where(b => b.Status == BundleBacktestRequestStatus.Running)
|
||||
.ToList();
|
||||
|
||||
foreach (var bundle in runningBundles)
|
||||
{
|
||||
var requestId = bundle.RequestId;
|
||||
if (string.IsNullOrEmpty(requestId)) continue;
|
||||
|
||||
// Fetch all backtests for this bundle
|
||||
var (backtests, _) = _backtester.GetBacktestsByRequestIdPaginated(requestId, 1, 100);
|
||||
if (!_sentBacktestIds.ContainsKey(requestId))
|
||||
_sentBacktestIds[requestId] = new HashSet<string>();
|
||||
|
||||
foreach (var backtest in backtests)
|
||||
{
|
||||
if (_sentBacktestIds[requestId].Contains(backtest.Id)) continue;
|
||||
|
||||
// If backtest is already LightBacktest, send directly
|
||||
var lightResponse = backtest as LightBacktest;
|
||||
if (lightResponse != null)
|
||||
{
|
||||
await _hubContext.Clients.Group($"bundle-{requestId}").SendAsync("BundleBacktestUpdate", lightResponse, stoppingToken);
|
||||
_sentBacktestIds[requestId].Add(backtest.Id);
|
||||
}
|
||||
}
|
||||
|
||||
// If the bundle is now completed, flush the sent IDs for this requestId
|
||||
if (bundle.Status == BundleBacktestRequestStatus.Completed && _sentBacktestIds.ContainsKey(requestId))
|
||||
{
|
||||
_sentBacktestIds.TryRemove(requestId, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error in NotifyBundleBacktestWorker");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user