feat(engine): OSRM travel provider with cache and fallback #90
No reviewers
Labels
No labels
in-progress
in-review
ready-for-agent
seam-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
patrick/Polaris!90
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/engine-osrm"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
Adds real OSRM-based travel-time routing to the planning engine, alongside the straight-line
(haversine) estimate it's had until now. When the OSRM router is reachable, the engine gets
actual road-network travel times instead of a straight-line guess; when it isn't — down, still
starting up, or simply not deployed in an environment — the engine quietly falls back to the
straight-line estimate instead of failing to produce a plan, and that fallback is recorded so a
planner reviewing the plan can see it was built on an estimate rather than real routing. Repeated
requests for the same set of locations are served from an in-memory cache instead of asking the
router again every time.
A standalone OSRM reachability check is also added, ready for the
/healthz//metricsendpointsto report on — see Additional Context for why that wiring isn't in this PR.
Related Issues
Closes #42. Row PH6.1 in
docs/12-implementation-plan.md. Files a follow-up: #89 (seamrequest, blocks #42).
Type of Change
Breaking Changes
None.
Test Plan
Tests green (
mypy --strict,ruff, full unit suite). Beyond the mocked-transport unit tests,this was also verified against a real, running OSRM process (
osrm/osrm-backend, the same imagethe compose stack uses) on a small road network built locally with
osrm-extract/partition/customize: real/tableresponse parsing and unit conversion, a cache hit skipping a secondHTTP call, and the fallback-then-recovery path by stopping and restarting that container mid-run.
The full Netherlands extract (
infra/osrm/prepare.sh) is a multi-GB download and a multi-minutebuild, impractical to run in this session — a compose-stack smoke test
(
backend/tests/integration/engine/osrm_smoke_test.py) is included for that, written to rununmodified once the real extract is up (
pytest -m smoke); it auto-skips otherwise, same as theexisting Keycloak smoke test.
Checklist
docs/updated for any behavioural change (ADR added if a prior decision was reversed)polaris.domainAdditional Context
This ticket's third acceptance criterion is only partially closed, and honestly so — see the
comment thread on #42 for the full explanation. Short version: making OSRM's reachability actually
show up as "degraded" on
GET /healthzrequires editingapi/routers/platform/health.pyandapi/metrics.py, both outside this row's owned paths (onlyengine/travel/osrm.pyandcore/health.pyare), and the router's current health status has no "degraded" state to reportinto yet. The probe itself (
check_osrm()) is complete, tested, and verified against a real OSRMprocess both up and down — I opened #89 (seam request, set to block #42) for the remaining wiring
rather than widening this ticket's scope.
Also out of scope for the same reason:
polaris.engine.solveandpolaris.worker.handlers.solvestill default to the haversine provider unconditionally — usingOSRM in a real solve needs one of them to construct
OsrmTravelMatrixProviderand readlast_call_sourceback intotravel_source. Both are sealed to other, already-merged rows(#18, #82); noted as a seam in
osrm.py's own module docstring for whoever next touches thosefiles, rather than filed as a separate issue since it's a smaller, lower-priority follow-up than
#89.
engine/travel.pybecame a package (engine/travel/__init__.py, content unchanged) soosrm.pyhas the module path this row specifies in
docs/12-implementation-plan.md; every existingfrom polaris.engine.travel import ...call site is unaffected.🤖 Generated with Claude Code
https://claude.ai/code/session_01LoNrSy7Reyp7evkfcdHeLX