mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 16:41:13 +00:00
[AZ-319] C11 HttpTileUploader (post-landing upload path)
Lands the production HttpTileUploader composing AZ-317's gate, AZ-318's per-flight signing, and consumer-side cuts over c6 storage. Implements the full upload flow: gate ON_GROUND -> start_session -> enumerate pending -> per-batch multipart POST with Ed25519 signing -> mark_uploaded on ack -> end_session in finally. Honours Retry-After (RFC 7231 int + HTTP-date), exponential backoff on 5xx, fail-fast on TLS/401/403. Adds C11Config block, three FDR kinds (tile.queued, tile.rejected, batch.complete), and the build_tile_uploader composition-root factory. Cross-component access to c6 stays Protocol-cut (AZ-507 / AZ-270). Tests: 17 new unit tests covering AC-1..AC-14 plus throughput NFR; AZ-272 schema fixtures for the three new FDR kinds. Full unit suite: 1404 passed. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
"""C11 TileManager config block (AZ-319).
|
||||
|
||||
Registered into ``config.components['c11_tile_manager']`` by the
|
||||
package ``__init__.py``. The composition-root factory
|
||||
:func:`gps_denied_onboard.runtime_root.c11_factory.build_tile_uploader`
|
||||
reads this block to drive the upload path's HTTP behaviour and to
|
||||
identify the producing companion against the parent suite's voting
|
||||
layer.
|
||||
|
||||
The four fields below match the AZ-319 task spec § ``Outcome`` —
|
||||
``config.c11.satellite_provider_ingest_url``,
|
||||
``config.c11.upload_batch_size``, ``config.c11.upload_http_timeout_s``,
|
||||
``config.c11.companion_id``. The ``upload_max_retry_after_s`` cap is
|
||||
the Risk-3 ceiling on cumulative ``Retry-After`` budget for 429
|
||||
responses (see :class:`RateLimitedError`).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from gps_denied_onboard.config.schema import ConfigError
|
||||
|
||||
__all__ = ["C11Config"]
|
||||
|
||||
|
||||
_DEFAULT_BATCH_SIZE: int = 25
|
||||
_DEFAULT_HTTP_TIMEOUT_S: float = 30.0
|
||||
_DEFAULT_MAX_RETRY_AFTER_S: int = 600
|
||||
_MAX_BATCH_SIZE: int = 200
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class C11Config:
|
||||
"""Per-component config for C11 tile manager (upload path).
|
||||
|
||||
``satellite_provider_ingest_url`` is the parent-suite ingest base
|
||||
URL (e.g. ``https://satellite-provider.example.com``); the
|
||||
uploader appends ``/api/satellite/tiles/ingest`` to it. Defaulted
|
||||
to empty so unit tests / replay runs that do not exercise the
|
||||
upload path stay no-op; production configuration MUST set this
|
||||
via YAML / env override or :class:`HttpTileUploader` raises
|
||||
:class:`SatelliteProviderError` on the first attempt.
|
||||
|
||||
``companion_id`` is the stable per-companion identifier the
|
||||
parent suite's voting layer uses to attribute uploads to one
|
||||
physical airframe. Defaulted to empty so test runs without a
|
||||
paired companion stay valid; the factory raises ``ConfigError``
|
||||
when the empty default is used in operator / production wiring.
|
||||
"""
|
||||
|
||||
satellite_provider_ingest_url: str = ""
|
||||
upload_batch_size: int = _DEFAULT_BATCH_SIZE
|
||||
upload_http_timeout_s: float = _DEFAULT_HTTP_TIMEOUT_S
|
||||
upload_max_retry_after_s: int = _DEFAULT_MAX_RETRY_AFTER_S
|
||||
companion_id: str = ""
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not 1 <= self.upload_batch_size <= _MAX_BATCH_SIZE:
|
||||
raise ConfigError(
|
||||
"C11Config.upload_batch_size must be in "
|
||||
f"[1, {_MAX_BATCH_SIZE}]; got {self.upload_batch_size}"
|
||||
)
|
||||
if self.upload_http_timeout_s <= 0:
|
||||
raise ConfigError(
|
||||
"C11Config.upload_http_timeout_s must be > 0; "
|
||||
f"got {self.upload_http_timeout_s}"
|
||||
)
|
||||
if self.upload_max_retry_after_s <= 0:
|
||||
raise ConfigError(
|
||||
"C11Config.upload_max_retry_after_s must be > 0; "
|
||||
f"got {self.upload_max_retry_after_s}"
|
||||
)
|
||||
Reference in New Issue
Block a user