mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 22:21:15 +00:00
23ab05766d
Replaces bare strings with two enums in Common/Enums/:
RegionStatus { Queued, Processing, Completed, Failed }
RoutePointType { Start, End, Action, Intermediate }
Adds a Dapper EnumStringTypeHandler<T> (DataAccess/TypeHandlers/)
that round-trips enums to/from lowercase strings, registered once
at startup via DapperEnumTypeHandlers.RegisterAll(). DataAccess now
references Common (project ref) so entities can carry the enum types.
Sites converted: RegionService (5), RouteProcessingService (3),
RoutePointGraphBuilder (4), entity Status/PointType columns. Log
message and summary file format preserved via .ToLowerInvariant().
API JSON contract preserved by adding JsonStringEnumConverter with
JsonNamingPolicy.CamelCase to the http JSON options — single-word
enum members serialize to the same lowercase strings as before.
DTO renamed: Common.DTO.RegionStatus -> RegionStatusResponse to
free the RegionStatus name for the new enum (forced by the task's
explicit enum name); the renamed DTO has no public-API impact at
the JSON wire level. Stale doc references updated.
AC RT2 in _docs/00_problem/acceptance_criteria.md now lists all 4
point types (start/end/action/intermediate).
Tests: 171 / 171 unit + 5 / 5 smoke green (was 141 + 5; +30 new tests
covering type handler round-trip, set/parse, unknown-value rejection,
idempotent registration, and the AC RT2 doc check).
Co-authored-by: Cursor <cursoragent@cursor.com>
3.8 KiB
3.8 KiB
Module: Services/RegionService + RegionProcessingService + RegionRequestQueue
Purpose
End-to-end region processing pipeline: API request handling → queue → background worker → tile download → output file generation. Three closely coupled classes form the region processing subsystem.
Public Interface
RegionService (implements IRegionService)
RequestRegionAsync(...): createsRegionEntitywith statusRegionStatus.Queued, enqueues aRegionRequest, returnsRegionStatusResponseGetRegionStatusAsync(Guid id): reads region record and maps toRegionStatusResponseProcessRegionAsync(Guid id, CancellationToken): the main processing pipeline — see Internal Logic
RegionProcessingService (BackgroundService)
ExecuteAsync(CancellationToken): spawnsMaxConcurrentRegionsparallel worker tasks, each in an infinite dequeue loop
RegionRequestQueue (implements IRegionRequestQueue)
EnqueueAsync(RegionRequest, CancellationToken): writes to a boundedChannel<RegionRequest>DequeueAsync(CancellationToken): reads from the channel (blocks until available)Count: current queue depth
Internal Logic
RegionService.ProcessRegionAsync
- Sets region status to "processing"
- Creates a 5-minute timeout
CancellationTokenSource - Queries existing tiles in the region
- Calls
TileService.DownloadAndStoreTilesAsyncto fetch missing tiles - Counts downloaded vs reused tiles
- Generates CSV file (
region_{id}_ready.csv) listing tile coordinates + paths - Optionally stitches tiles into a single JPEG image (if
StitchTilesis true) - Generates summary file (
region_{id}_summary.txt) - Updates region status to "completed"
- On any error: sets status to "failed", generates error summary
Tile Stitching
Uses ImageSharp to:
- Compute a tile grid from tile coordinates
- Create a new image of
(gridWidth × 256) × (gridHeight × 256)pixels - Place each tile image at its grid position
- Draw a red crosshair at the center coordinates
- Save as JPEG
Error Handling
Comprehensive catch blocks for:
TaskCanceledException(timeout vs external cancellation)OperationCanceledExceptionRateLimitException(Google rate limiting)HttpRequestException(with status code)- Generic
ExceptionEach sets status to "failed" and writes an error summary file.
RegionProcessingService
- Spawns
MaxConcurrentRegionsworker tasks with staggered startup (100–500ms random delay) - Each worker loops: dequeue →
ProcessRegionAsync→ repeat - Graceful shutdown on cancellation
RegionRequestQueue
- Uses
System.Threading.Channels.Channel<T>.CreateBoundedwithBoundedChannelFullMode.Wait - Tracks
_totalEnqueuedand_totalDequeuedcounters
Dependencies
ITileService,IRegionRepository,IRegionRequestQueueStorageConfig,ProcessingConfigSixLabors.ImageSharp— tile stitchingSatelliteProvider.Common.Utils.GeoUtils— coordinate conversion for stitching
Consumers
Program.csAPI endpoints —RequestRegionAsync,GetRegionStatusAsyncRouteService—RequestRegionAsync(for geofence regions)RouteProcessingService—RequestRegionAsync(for route-point regions)
Data Models
- Input:
RegionRequest(queue message) - Output:
RegionStatusResponse(API response), CSV files, summary files, stitched images - Persistence:
RegionEntity
Configuration
StorageConfig.ReadyDirectory— output file locationProcessingConfig.MaxConcurrentRegions— worker countProcessingConfig.QueueCapacity— bounded channel size
External Integrations
- PostgreSQL (via repositories)
- File system (CSV, summary, stitched images in
./ready/) - Google Maps (indirectly via TileService → GoogleMapsDownloaderV2)
Security
None.
Tests
Integration tests in RegionTests.cs cover the request → poll → complete flow.