mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-04-22 23:46:38 +00:00
more complex route
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -14,18 +15,21 @@ public class RouteProcessingService : BackgroundService
|
||||
{
|
||||
private readonly IRouteRepository _routeRepository;
|
||||
private readonly IRegionRepository _regionRepository;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly StorageConfig _storageConfig;
|
||||
private readonly ILogger<RouteProcessingService> _logger;
|
||||
private readonly TimeSpan _checkInterval = TimeSpan.FromSeconds(10);
|
||||
private readonly TimeSpan _checkInterval = TimeSpan.FromSeconds(5);
|
||||
|
||||
public RouteProcessingService(
|
||||
IRouteRepository routeRepository,
|
||||
IRegionRepository regionRepository,
|
||||
IServiceProvider serviceProvider,
|
||||
IOptions<StorageConfig> storageConfig,
|
||||
ILogger<RouteProcessingService> logger)
|
||||
{
|
||||
_routeRepository = routeRepository;
|
||||
_regionRepository = regionRepository;
|
||||
_serviceProvider = serviceProvider;
|
||||
_storageConfig = storageConfig.Value;
|
||||
_logger = logger;
|
||||
}
|
||||
@@ -62,7 +66,7 @@ public class RouteProcessingService : BackgroundService
|
||||
|
||||
try
|
||||
{
|
||||
await ProcessRouteIfReadyAsync(route.Id, cancellationToken);
|
||||
await ProcessRouteSequentiallyAsync(route.Id, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -77,7 +81,7 @@ public class RouteProcessingService : BackgroundService
|
||||
return routes.Select(r => (r.Id, r.RequestMaps)).ToList();
|
||||
}
|
||||
|
||||
private async Task ProcessRouteIfReadyAsync(Guid routeId, CancellationToken cancellationToken)
|
||||
private async Task ProcessRouteSequentiallyAsync(Guid routeId, CancellationToken cancellationToken)
|
||||
{
|
||||
var route = await _routeRepository.GetByIdAsync(routeId);
|
||||
if (route == null || !route.RequestMaps || route.MapsReady)
|
||||
@@ -85,49 +89,84 @@ public class RouteProcessingService : BackgroundService
|
||||
return;
|
||||
}
|
||||
|
||||
var regionIds = await _routeRepository.GetRegionIdsByRouteAsync(routeId);
|
||||
if (!regionIds.Any())
|
||||
var routePointsList = (await _routeRepository.GetRoutePointsAsync(routeId)).ToList();
|
||||
var regionIdsList = (await _routeRepository.GetRegionIdsByRouteAsync(routeId)).ToList();
|
||||
|
||||
if (regionIdsList.Count == 0)
|
||||
{
|
||||
_logger.LogWarning("Route {RouteId} has no regions linked", routeId);
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var regionService = scope.ServiceProvider.GetRequiredService<Common.Interfaces.IRegionService>();
|
||||
|
||||
_logger.LogInformation("Route {RouteId}: Starting sequential region processing for {PointCount} points",
|
||||
routeId, routePointsList.Count);
|
||||
|
||||
var firstPoint = routePointsList.First();
|
||||
var regionId = Guid.NewGuid();
|
||||
|
||||
await regionService.RequestRegionAsync(
|
||||
regionId,
|
||||
firstPoint.Latitude,
|
||||
firstPoint.Longitude,
|
||||
route.RegionSizeMeters,
|
||||
route.ZoomLevel,
|
||||
stitchTiles: false);
|
||||
|
||||
await _routeRepository.LinkRouteToRegionAsync(routeId, regionId);
|
||||
|
||||
_logger.LogInformation("Route {RouteId}: Queued first region {RegionId} (1/{TotalPoints})",
|
||||
routeId, regionId, routePointsList.Count);
|
||||
return;
|
||||
}
|
||||
|
||||
var allCompleted = true;
|
||||
var anyFailed = false;
|
||||
|
||||
foreach (var regionId in regionIds)
|
||||
{
|
||||
var region = await _regionRepository.GetByIdAsync(regionId);
|
||||
if (region == null)
|
||||
{
|
||||
_logger.LogWarning("Region {RegionId} not found for route {RouteId}", regionId, routeId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (region.Status == "failed")
|
||||
{
|
||||
anyFailed = true;
|
||||
}
|
||||
else if (region.Status != "completed")
|
||||
{
|
||||
allCompleted = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allCompleted)
|
||||
|
||||
var lastRegion = await _regionRepository.GetByIdAsync(regionIdsList.Last());
|
||||
if (lastRegion == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (anyFailed)
|
||||
|
||||
if (lastRegion.Status == "queued" || lastRegion.Status == "processing")
|
||||
{
|
||||
_logger.LogWarning("Route {RouteId} has failed regions, skipping processing", routeId);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation("All regions completed for route {RouteId}, starting final processing", routeId);
|
||||
|
||||
await GenerateRouteMapsAsync(routeId, route, regionIds, cancellationToken);
|
||||
|
||||
if (lastRegion.Status == "failed")
|
||||
{
|
||||
_logger.LogError("Route {RouteId}: Region {RegionId} failed. Stopping route processing.",
|
||||
routeId, lastRegion.Id);
|
||||
|
||||
route.MapsReady = false;
|
||||
route.UpdatedAt = DateTime.UtcNow;
|
||||
await _routeRepository.UpdateRouteAsync(route);
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionIdsList.Count < routePointsList.Count)
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var regionService = scope.ServiceProvider.GetRequiredService<Common.Interfaces.IRegionService>();
|
||||
|
||||
var nextPoint = routePointsList[regionIdsList.Count];
|
||||
var regionId = Guid.NewGuid();
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Route {RouteId}: All {RegionCount} regions completed, generating final maps",
|
||||
routeId, regionIdsList.Count);
|
||||
|
||||
await GenerateRouteMapsAsync(routeId, route, regionIdsList, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task GenerateRouteMapsAsync(
|
||||
@@ -353,8 +392,8 @@ public class RouteProcessingService : BackgroundService
|
||||
|
||||
if (tileImage.Width != tileSizePixels || tileImage.Height != tileSizePixels)
|
||||
{
|
||||
_logger.LogWarning("Tile {FilePath} has wrong size {Width}x{Height}, expected {Expected}x{Expected}",
|
||||
tile.FilePath, tileImage.Width, tileImage.Height, tileSizePixels);
|
||||
_logger.LogWarning("Tile {FilePath} has wrong size {Width}x{Height}, expected {ExpectedWidth}x{ExpectedHeight}",
|
||||
tile.FilePath, tileImage.Width, tileImage.Height, tileSizePixels, tileSizePixels);
|
||||
}
|
||||
|
||||
stitchedImage.Mutate(ctx => ctx.DrawImage(tileImage, new Point(destX, destY), 1f));
|
||||
|
||||
Reference in New Issue
Block a user