Files
satellite-provider/_docs/02_document/modules/services_region.md
T
Oleksandr Bezdieniezhnykh b0fffa6d42 [AZ-284] Autodev baseline + testability refactor
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>
2026-05-10 04:44:08 +03:00

3.8 KiB
Raw Blame History

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 (100500ms 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
  • RouteServiceRequestRegionAsync (for geofence regions)
  • RouteProcessingServiceRequestRegionAsync (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.