-
Andrey Azeev authored
Final whole-branch review, Important C, D, A, E and doc corrections (F). Important C: `Retry-After` from the source was applied unbounded -- `Retry-After: 3600` could park one page for an hour, five hours across retryAttempts=5, with no overall tick deadline. Delay computation moved into a pure `_resolve_backoff_delay` (testable without mocking asyncio.sleep) and clamped to `CustomerSourceSettings. maxRetryAfterSeconds` (default 30s); negative values clamp to zero. Important D: `set_sync_status` only wrote three of the four fields the design's section 10 lists. Added `lastSyncFinishedAt` (self-stamped, same `time.time()` pattern as `updatedAt`) through the `BalanceStore` port and both implementations, plus a new `bonus_last_sync_attempt_age_seconds` gauge alongside the existing age-of-data one -- without it a scheduler that dies right after a successful tick looks identical to a healthy one on every existing signal. Important A: `bonus_snapshot_rows` gauge, fed from `meta["count"]` which `refresh_snapshot_metrics` already read and discarded -- this is the metric that would have surfaced both blockers on a dashboard before `bonus_snapshot_age_seconds` had a chance to notice anything. Important E: `stop_grace_period: 240s` on the `scheduler` service in both compose files (measured sweep is 170s) so a redeploy landing mid-sweep gets SIGTERM instead of SIGKILL. Loop/stop_event logic untouched, per review note -- cancelling a running tick is a follow-up. Doc corrections (F): README's `APP__HALYK_SNAPSHOT_MAXITEMS` default (200000 -> 1000000, matching code) and peak-memory figure (56 MiB -> ~130 MB, matching measurement); snapshot schema module/SnapshotResult docstrings rewritten as internal DTOs, not HTTP contract, now that POST /internal/bonus/snapshot is deleted; new settings documented in .env.example. Claude-Session: https://claude.ai/code/session_01681igANZDJCmrQJaWPNk26
cdef0d38Andrey Azeev authoredFinal whole-branch review, Important C, D, A, E and doc corrections (F). Important C: `Retry-After` from the source was applied unbounded -- `Retry-After: 3600` could park one page for an hour, five hours across retryAttempts=5, with no overall tick deadline. Delay computation moved into a pure `_resolve_backoff_delay` (testable without mocking asyncio.sleep) and clamped to `CustomerSourceSettings. maxRetryAfterSeconds` (default 30s); negative values clamp to zero. Important D: `set_sync_status` only wrote three of the four fields the design's section 10 lists. Added `lastSyncFinishedAt` (self-stamped, same `time.time()` pattern as `updatedAt`) through the `BalanceStore` port and both implementations, plus a new `bonus_last_sync_attempt_age_seconds` gauge alongside the existing age-of-data one -- without it a scheduler that dies right after a successful tick looks identical to a healthy one on every existing signal. Important A: `bonus_snapshot_rows` gauge, fed from `meta["count"]` which `refresh_snapshot_metrics` already read and discarded -- this is the metric that would have surfaced both blockers on a dashboard before `bonus_snapshot_age_seconds` had a chance to notice anything. Important E: `stop_grace_period: 240s` on the `scheduler` service in both compose files (measured sweep is 170s) so a redeploy landing mid-sweep gets SIGTERM instead of SIGKILL. Loop/stop_event logic untouched, per review note -- cancelling a running tick is a follow-up. Doc corrections (F): README's `APP__HALYK_SNAPSHOT_MAXITEMS` default (200000 -> 1000000, matching code) and peak-memory figure (56 MiB -> ~130 MB, matching measurement); snapshot schema module/SnapshotResult docstrings rewritten as internal DTOs, not HTTP contract, now that POST /internal/bonus/snapshot is deleted; new settings documented in .env.example. Claude-Session: https://claude.ai/code/session_01681igANZDJCmrQJaWPNk26
Loading