Fix styling, job endpoints, and infinite worker loops
This commit is contained in:
@@ -444,7 +444,7 @@ body {
|
|||||||
.menubar-divider { width: 1px; height: 24px; background: var(--border); }
|
.menubar-divider { width: 1px; height: 24px; background: var(--border); }
|
||||||
.btn-outline { background: var(--bg-input); color: var(--text); border: 1px solid var(--border); border-radius: 6px; cursor: pointer; font-weight: 500; transition: all 0.2s; }
|
.btn-outline { background: var(--bg-input); color: var(--text); border: 1px solid var(--border); border-radius: 6px; cursor: pointer; font-weight: 500; transition: all 0.2s; }
|
||||||
.btn-outline:hover { background: var(--border); }
|
.btn-outline:hover { background: var(--border); }
|
||||||
.btn-primary { background: var(--primary); color: #000; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; transition: all 0.2s; }
|
.btn-primary { background: var(--accent); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; transition: all 0.2s; }
|
||||||
.btn-primary:hover { filter: brightness(1.1); }
|
.btn-primary:hover { filter: brightness(1.1); }
|
||||||
.tabs-nav { display: flex; gap: 12px; margin-bottom: 24px; border-bottom: 1px solid var(--border); padding-bottom: 8px; flex-wrap: wrap; align-items: center; }
|
.tabs-nav { display: flex; gap: 12px; margin-bottom: 24px; border-bottom: 1px solid var(--border); padding-bottom: 8px; flex-wrap: wrap; align-items: center; }
|
||||||
.btn-tab {
|
.btn-tab {
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ public class EmbeddedWebServer
|
|||||||
app.MapMarketEndpoints();
|
app.MapMarketEndpoints();
|
||||||
app.MapAlertEndpoints();
|
app.MapAlertEndpoints();
|
||||||
app.MapSearchEndpoints();
|
app.MapSearchEndpoints();
|
||||||
|
app.MapJobEndpoints();
|
||||||
app.MapGet("/api/health", () => Results.Ok(new { Status = "OK", Timestamp = DateTime.UtcNow }));
|
app.MapGet("/api/health", () => Results.Ok(new { Status = "OK", Timestamp = DateTime.UtcNow }));
|
||||||
|
|
||||||
await Predictalytics.Infrastructure.DependencyInjection.EnsureDatabaseAsync(app.Services, DbConnectionDebug);
|
await Predictalytics.Infrastructure.DependencyInjection.EnsureDatabaseAsync(app.Services, DbConnectionDebug);
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ public class TradeHistoryWorker : BackgroundService
|
|||||||
|
|
||||||
while (!stoppingToken.IsCancellationRequested)
|
while (!stoppingToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
|
IReadOnlyList<Domain.Entities.Trader> tradersToProcess = new List<Domain.Entities.Trader>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IReadOnlyList<Domain.Entities.Trader> tradersToProcess = new List<Domain.Entities.Trader>();
|
|
||||||
Domain.Entities.BackgroundJob? activeJob = null;
|
Domain.Entities.BackgroundJob? activeJob = null;
|
||||||
|
|
||||||
using (var scope = _services.CreateScope())
|
using (var scope = _services.CreateScope())
|
||||||
@@ -260,7 +260,10 @@ public class TradeHistoryWorker : BackgroundService
|
|||||||
}
|
}
|
||||||
catch (Exception ex) { _logger.LogError(ex, "TradeHistoryWorker error"); }
|
catch (Exception ex) { _logger.LogError(ex, "TradeHistoryWorker error"); }
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromMinutes(2), stoppingToken);
|
if (tradersToProcess == null || tradersToProcess.Count == 0)
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromMinutes(2), stoppingToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("📜 TradeHistoryWorker stopped");
|
_logger.LogInformation("📜 TradeHistoryWorker stopped");
|
||||||
|
|||||||
@@ -27,19 +27,22 @@ public class TraderAnalyticsWorker : BackgroundService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await RunAnalyticsAsync(ct);
|
var processedCount = await RunAnalyticsAsync(ct);
|
||||||
|
if (processedCount == 0)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("TraderAnalyticsWorker sleeping for 1 minute...");
|
||||||
|
await Task.Delay(TimeSpan.FromMinutes(1), ct);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error in TraderAnalyticsWorker");
|
_logger.LogError(ex, "Error in TraderAnalyticsWorker");
|
||||||
|
await Task.Delay(TimeSpan.FromMinutes(1), ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("TraderAnalyticsWorker sleeping for 2 hours...");
|
|
||||||
await Task.Delay(TimeSpan.FromHours(2), ct);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RunAnalyticsAsync(CancellationToken ct)
|
private async Task<int> RunAnalyticsAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
List<int> traderIds = new List<int>();
|
List<int> traderIds = new List<int>();
|
||||||
Domain.Entities.BackgroundJob? activeJob = null;
|
Domain.Entities.BackgroundJob? activeJob = null;
|
||||||
@@ -104,8 +107,9 @@ public class TraderAnalyticsWorker : BackgroundService
|
|||||||
scoreObj.CalculatedAt = DateTime.UtcNow;
|
scoreObj.CalculatedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
trader.CurrentScore = scoreObj;
|
trader.CurrentScore = scoreObj;
|
||||||
await traderRepo.UpdateAsync(trader, ct);
|
|
||||||
}
|
}
|
||||||
|
trader.LastAnalyzedAt = DateTime.UtcNow;
|
||||||
|
await traderRepo.UpdateAsync(trader, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeJob != null && activeJob.TraderId == id)
|
if (activeJob != null && activeJob.TraderId == id)
|
||||||
@@ -138,5 +142,7 @@ public class TraderAnalyticsWorker : BackgroundService
|
|||||||
{
|
{
|
||||||
_logger.LogInformation("Trader analytics update complete.");
|
_logger.LogInformation("Trader analytics update complete.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return traderIds.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user