mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 19:11:14 +00:00
b0fffa6d42
Phase A baseline outputs from /autodev (Steps 1-5): - Problem & solution docs (_docs/00_problem, _docs/01_solution) - Codebase documentation (_docs/02_document) incl. architecture, module-layout, glossary, system-flows, baseline compliance scan - Test specs (blackbox, performance, resilience, security, resource, traceability matrix) - Test task decomposition (_docs/02_tasks/todo): AZ-285..AZ-290 - Testability refactor (_docs/04_refactoring/01-testability-refactoring): - TC-01 Move DownloadedTileInfoV2 + new ExistingTileInfo to Common.DTO - TC-02 Replace dead ISatelliteDownloader API with real signatures - TC-03 GoogleMapsDownloaderV2 implements ISatelliteDownloader - TC-04 TileService depends on ISatelliteDownloader (mockable) - TC-05 DI + endpoints use ISatelliteDownloader - Test runner scripts (scripts/run-tests.sh, run-performance-tests.sh) - Autodev state pointer (_docs/_autodev_state.md) Prepares the codebase for AZ-285..AZ-290 unit/integration test work. Co-authored-by: Cursor <cursoragent@cursor.com>
92 lines
3.8 KiB
Markdown
92 lines
3.8 KiB
Markdown
# 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(...)`: creates `RegionEntity` with status "queued", enqueues a `RegionRequest`, returns `RegionStatus`
|
||
- `GetRegionStatusAsync(Guid id)`: reads region record and maps to `RegionStatus`
|
||
- `ProcessRegionAsync(Guid id, CancellationToken)`: the main processing pipeline — see Internal Logic
|
||
|
||
### RegionProcessingService (BackgroundService)
|
||
- `ExecuteAsync(CancellationToken)`: spawns `MaxConcurrentRegions` parallel worker tasks, each in an infinite dequeue loop
|
||
|
||
### RegionRequestQueue (implements IRegionRequestQueue)
|
||
- `EnqueueAsync(RegionRequest, CancellationToken)`: writes to a bounded `Channel<RegionRequest>`
|
||
- `DequeueAsync(CancellationToken)`: reads from the channel (blocks until available)
|
||
- `Count`: current queue depth
|
||
|
||
## Internal Logic
|
||
|
||
### RegionService.ProcessRegionAsync
|
||
1. Sets region status to "processing"
|
||
2. Creates a 5-minute timeout `CancellationTokenSource`
|
||
3. Queries existing tiles in the region
|
||
4. Calls `TileService.DownloadAndStoreTilesAsync` to fetch missing tiles
|
||
5. Counts downloaded vs reused tiles
|
||
6. Generates CSV file (`region_{id}_ready.csv`) listing tile coordinates + paths
|
||
7. Optionally stitches tiles into a single JPEG image (if `StitchTiles` is true)
|
||
8. Generates summary file (`region_{id}_summary.txt`)
|
||
9. Updates region status to "completed"
|
||
10. On any error: sets status to "failed", generates error summary
|
||
|
||
### Tile Stitching
|
||
Uses ImageSharp to:
|
||
1. Compute a tile grid from tile coordinates
|
||
2. Create a new image of `(gridWidth × 256) × (gridHeight × 256)` pixels
|
||
3. Place each tile image at its grid position
|
||
4. Draw a red crosshair at the center coordinates
|
||
5. Save as JPEG
|
||
|
||
### Error Handling
|
||
Comprehensive catch blocks for:
|
||
- `TaskCanceledException` (timeout vs external cancellation)
|
||
- `OperationCanceledException`
|
||
- `RateLimitException` (Google rate limiting)
|
||
- `HttpRequestException` (with status code)
|
||
- Generic `Exception`
|
||
Each sets status to "failed" and writes an error summary file.
|
||
|
||
### RegionProcessingService
|
||
- Spawns `MaxConcurrentRegions` worker 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>.CreateBounded` with `BoundedChannelFullMode.Wait`
|
||
- Tracks `_totalEnqueued` and `_totalDequeued` counters
|
||
|
||
## Dependencies
|
||
- `ITileService`, `IRegionRepository`, `IRegionRequestQueue`
|
||
- `StorageConfig`, `ProcessingConfig`
|
||
- `SixLabors.ImageSharp` — tile stitching
|
||
- `SatelliteProvider.Common.Utils.GeoUtils` — coordinate conversion for stitching
|
||
|
||
## Consumers
|
||
- `Program.cs` API endpoints — `RequestRegionAsync`, `GetRegionStatusAsync`
|
||
- `RouteService` — `RequestRegionAsync` (for geofence regions)
|
||
- `RouteProcessingService` — `RequestRegionAsync` (for route-point regions)
|
||
|
||
## Data Models
|
||
- Input: `RegionRequest` (queue message)
|
||
- Output: `RegionStatus` (API response), CSV files, summary files, stitched images
|
||
- Persistence: `RegionEntity`
|
||
|
||
## Configuration
|
||
- `StorageConfig.ReadyDirectory` — output file location
|
||
- `ProcessingConfig.MaxConcurrentRegions` — worker count
|
||
- `ProcessingConfig.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.
|