mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-04-22 09:06:38 +00:00
parallel processing for routes and regions
This commit is contained in:
@@ -97,76 +97,95 @@ public class RouteProcessingService : BackgroundService
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var regionService = scope.ServiceProvider.GetRequiredService<Common.Interfaces.IRegionService>();
|
||||
|
||||
_logger.LogInformation("Route {RouteId}: Starting sequential region processing for {PointCount} points",
|
||||
_logger.LogInformation("Route {RouteId}: Starting parallel region processing for {PointCount} points",
|
||||
routeId, routePointsList.Count);
|
||||
|
||||
var firstPoint = routePointsList.First();
|
||||
var regionId = Guid.NewGuid();
|
||||
var queuedRegionIds = new List<Guid>();
|
||||
|
||||
await regionService.RequestRegionAsync(
|
||||
regionId,
|
||||
firstPoint.Latitude,
|
||||
firstPoint.Longitude,
|
||||
route.RegionSizeMeters,
|
||||
route.ZoomLevel,
|
||||
stitchTiles: false);
|
||||
foreach (var point in routePointsList)
|
||||
{
|
||||
var regionId = Guid.NewGuid();
|
||||
|
||||
await regionService.RequestRegionAsync(
|
||||
regionId,
|
||||
point.Latitude,
|
||||
point.Longitude,
|
||||
route.RegionSizeMeters,
|
||||
route.ZoomLevel,
|
||||
stitchTiles: false);
|
||||
|
||||
await _routeRepository.LinkRouteToRegionAsync(routeId, regionId);
|
||||
queuedRegionIds.Add(regionId);
|
||||
}
|
||||
|
||||
await _routeRepository.LinkRouteToRegionAsync(routeId, regionId);
|
||||
|
||||
_logger.LogInformation("Route {RouteId}: Queued first region {RegionId} (1/{TotalPoints})",
|
||||
routeId, regionId, routePointsList.Count);
|
||||
_logger.LogInformation("Route {RouteId}: Queued all {Count} regions for parallel processing. Region IDs: {RegionIds}",
|
||||
routeId, queuedRegionIds.Count, string.Join(", ", queuedRegionIds.Take(5)) + (queuedRegionIds.Count > 5 ? "..." : ""));
|
||||
return;
|
||||
}
|
||||
|
||||
var lastRegion = await _regionRepository.GetByIdAsync(regionIdsList.Last());
|
||||
if (lastRegion == null)
|
||||
var regions = new List<DataAccess.Models.RegionEntity>();
|
||||
foreach (var regionId in regionIdsList)
|
||||
{
|
||||
return;
|
||||
var region = await _regionRepository.GetByIdAsync(regionId);
|
||||
if (region != null)
|
||||
{
|
||||
regions.Add(region);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastRegion.Status == "queued" || lastRegion.Status == "processing")
|
||||
{
|
||||
return;
|
||||
}
|
||||
var completedRegions = regions.Where(r => r.Status == "completed").ToList();
|
||||
var failedRegions = regions.Where(r => r.Status == "failed").ToList();
|
||||
var processingRegions = regions.Where(r => r.Status == "queued" || r.Status == "processing").ToList();
|
||||
|
||||
if (lastRegion.Status == "failed")
|
||||
var hasEnoughCompleted = completedRegions.Count >= routePointsList.Count;
|
||||
var activeRegions = completedRegions.Count + processingRegions.Count;
|
||||
var shouldRetryFailed = failedRegions.Count > 0 && !hasEnoughCompleted && activeRegions < routePointsList.Count;
|
||||
|
||||
if (hasEnoughCompleted)
|
||||
{
|
||||
_logger.LogError("Route {RouteId}: Region {RegionId} failed. Stopping route processing.",
|
||||
routeId, lastRegion.Id);
|
||||
_logger.LogInformation("Route {RouteId}: Have {Completed} completed regions (required: {Required}). Generating final maps. Ignoring {Processing} processing and {Failed} failed regions.",
|
||||
routeId, completedRegions.Count, routePointsList.Count, processingRegions.Count, failedRegions.Count);
|
||||
|
||||
route.MapsReady = false;
|
||||
route.UpdatedAt = DateTime.UtcNow;
|
||||
await _routeRepository.UpdateRouteAsync(route);
|
||||
await GenerateRouteMapsAsync(routeId, route, completedRegions.Take(routePointsList.Count).Select(r => r.Id), cancellationToken);
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionIdsList.Count < routePointsList.Count)
|
||||
if (shouldRetryFailed)
|
||||
{
|
||||
_logger.LogWarning("Route {RouteId}: {FailedCount} region(s) failed: {FailedRegions}. Active regions: {ActiveCount}/{RequiredCount}. Attempting to retry with new regions.",
|
||||
routeId, failedRegions.Count, string.Join(", ", failedRegions.Select(r => r.Id)), activeRegions, routePointsList.Count);
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var regionService = scope.ServiceProvider.GetRequiredService<Common.Interfaces.IRegionService>();
|
||||
|
||||
var nextPoint = routePointsList[regionIdsList.Count];
|
||||
var regionId = Guid.NewGuid();
|
||||
foreach (var failedRegion in failedRegions)
|
||||
{
|
||||
var newRegionId = Guid.NewGuid();
|
||||
_logger.LogInformation("Route {RouteId}: Retrying failed region {OldRegionId} with new region {NewRegionId}",
|
||||
routeId, failedRegion.Id, newRegionId);
|
||||
|
||||
await regionService.RequestRegionAsync(
|
||||
newRegionId,
|
||||
failedRegion.Latitude,
|
||||
failedRegion.Longitude,
|
||||
failedRegion.SizeMeters,
|
||||
failedRegion.ZoomLevel,
|
||||
stitchTiles: false);
|
||||
|
||||
await _routeRepository.LinkRouteToRegionAsync(routeId, newRegionId);
|
||||
}
|
||||
|
||||
await regionService.RequestRegionAsync(
|
||||
regionId,
|
||||
nextPoint.Latitude,
|
||||
nextPoint.Longitude,
|
||||
route.RegionSizeMeters,
|
||||
route.ZoomLevel,
|
||||
stitchTiles: false);
|
||||
|
||||
await _routeRepository.LinkRouteToRegionAsync(routeId, regionId);
|
||||
|
||||
_logger.LogInformation("Route {RouteId}: Queued next region {RegionId} ({CurrentRegion}/{TotalPoints})",
|
||||
routeId, regionId, regionIdsList.Count + 1, routePointsList.Count);
|
||||
_logger.LogInformation("Route {RouteId}: Queued {Count} retry regions", routeId, failedRegions.Count);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Route {RouteId}: All {RegionCount} regions completed, generating final maps",
|
||||
routeId, regionIdsList.Count);
|
||||
|
||||
await GenerateRouteMapsAsync(routeId, route, regionIdsList, cancellationToken);
|
||||
var anyProcessing = processingRegions.Count > 0;
|
||||
if (anyProcessing)
|
||||
{
|
||||
_logger.LogInformation("Route {RouteId}: Progress - {Completed}/{Required} regions completed, {Processing} still processing, {Failed} failed (will retry if needed)",
|
||||
routeId, completedRegions.Count, routePointsList.Count, processingRegions.Count, failedRegions.Count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task GenerateRouteMapsAsync(
|
||||
|
||||
Reference in New Issue
Block a user