auto-sync: 2026-05-04 11:40:01
This commit is contained in:
@@ -497,6 +497,33 @@ async def post_route(req: RouteRequest):
|
||||
except Exception as e:
|
||||
raise HTTPException(503, f"OSRM недоступен: {e}")
|
||||
|
||||
# OSRM возвращает TooBig когда маршрут слишком длинный для N альтернатив
|
||||
if data.get("code") == "TooBig":
|
||||
# Пробуем с меньшим числом альтернатив
|
||||
url_retry3 = (
|
||||
f"{OSRM_URL}/route/v1/driving/{coords_str}"
|
||||
f"?alternatives=3&overview=full&geometries=geojson&annotations=false"
|
||||
)
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.get(url_retry3)
|
||||
data = resp.json()
|
||||
except Exception as e:
|
||||
raise HTTPException(503, f"OSRM недоступен: {e}")
|
||||
|
||||
if data.get("code") == "TooBig":
|
||||
# Всё ещё TooBig — пробуем совсем без альтернатив
|
||||
url_retry1 = (
|
||||
f"{OSRM_URL}/route/v1/driving/{coords_str}"
|
||||
f"?overview=full&geometries=geojson&alternatives=false"
|
||||
)
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.get(url_retry1)
|
||||
data = resp.json()
|
||||
except Exception as e:
|
||||
raise HTTPException(503, f"OSRM недоступен: {e}")
|
||||
|
||||
if data.get("code") != "Ok" or not data.get("routes"):
|
||||
raise HTTPException(404, "Маршрут не найден")
|
||||
|
||||
|
||||
1
tasks/enduro-trails/prototype/static/app.js
vendored
1
tasks/enduro-trails/prototype/static/app.js
vendored
@@ -7,6 +7,7 @@ function formatDuration(seconds) {
|
||||
const hours = Math.floor((totalMin % 1440) / 60);
|
||||
const mins = totalMin % 60;
|
||||
if (days > 0) {
|
||||
if (hours === 0 && mins === 0) return `${days} дн`;
|
||||
if (mins === 0) return `${days} дн ${hours} ч`;
|
||||
return `${days} дн ${hours} ч ${mins} мин`;
|
||||
}
|
||||
|
||||
75
tasks/enduro-trails/reports/dev-2026-05-04-phase3-bugfix.md
Normal file
75
tasks/enduro-trails/reports/dev-2026-05-04-phase3-bugfix.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Dev Report: Enduro Trails Фаза 3 — Bugfix
|
||||
Дата: 2026-05-04
|
||||
Статус: DONE
|
||||
|
||||
## Задача
|
||||
Исправить 2 бага в Enduro Trails Фаза 3:
|
||||
1. app.py: OSRM возвращает `code: "TooBig"` при `alternatives=5` → 404
|
||||
2. app.js: `formatDuration(86400)` → `"1 дн 0 ч"` вместо `"1 дн"`
|
||||
|
||||
## Сделано
|
||||
- [x] Прочитал app.py и app.js
|
||||
- [x] Баг 1: добавил retry-логику в POST `/api/route` — сначала `alternatives=3`, затем `alternatives=false`
|
||||
- [x] Баг 2: исправил ветку `days > 0` в `formatDuration` — добавил проверку `hours === 0 && mins === 0`
|
||||
- [x] Обновил файлы в workspace
|
||||
- [x] Задеплоил через Node.js ssh2 (SSH бинарник не работает из контейнера — GLIBC mismatch)
|
||||
- [x] Обнаружил что контейнер собран из образа (не bind-mount) → использовал `docker cp` для копирования файлов в контейнер
|
||||
- [x] Перезапустил контейнер (`docker compose restart`)
|
||||
- [x] Проверил что фикс выжил после рестарта (TooBig: 4 вхождения в контейнере)
|
||||
- [x] Прогнал тест — маршрут возвращается, pct sum = 100
|
||||
|
||||
## Изменённые файлы
|
||||
- `workspace/tasks/enduro-trails/prototype/app.py` — retry-логика TooBig (строки ~500-525)
|
||||
- `workspace/tasks/enduro-trails/prototype/static/app.js` — formatDuration fix
|
||||
|
||||
## Результат
|
||||
|
||||
### Баг 1 — TooBig fix
|
||||
OSRM на mva154 имеет максимум 3 альтернативы (не 5). Любой запрос с `alternatives=5` возвращает `TooBig`.
|
||||
Retry-цепочка: `alternatives=5` → TooBig → `alternatives=3` → если снова TooBig → `alternatives=false`.
|
||||
|
||||
Тест короткого маршрута (37.6184,55.7512 → 37.8,55.85):
|
||||
```
|
||||
routes count: 3
|
||||
distance_m: 18858
|
||||
pct sum: 100 OK
|
||||
```
|
||||
|
||||
Тест длинного маршрута ~127км (37.6184,55.7512 → 36.7,56.3):
|
||||
```
|
||||
routes count: 1
|
||||
distance_m: 127088
|
||||
pct sum: 100 OK
|
||||
```
|
||||
|
||||
### Баг 2 — formatDuration fix
|
||||
```
|
||||
formatDuration(86400): "1 дн" ✅ (было "1 дн 0 ч")
|
||||
formatDuration(90000): "1 дн 1 ч" ✅
|
||||
formatDuration(93600): "1 дн 2 ч" ✅
|
||||
```
|
||||
|
||||
## Проблемы и решения
|
||||
|
||||
### SSH бинарник не работает из контейнера
|
||||
GLIBC mismatch: `ssh: /lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.38' not found`
|
||||
→ Решение: Node.js скрипт с npm `ssh2` для всех SSH операций.
|
||||
|
||||
### Stale lock на mva154
|
||||
Осталась незавершённая сессия от 2026-05-03 (add-swap-4g). PID 78077 мёртв.
|
||||
→ Решение: удалил lock directory вручную, создал новую сессию.
|
||||
|
||||
### Контейнер собран из образа (не bind-mount)
|
||||
`docker compose restart` перезапускает контейнер из существующего образа — файлы на хосте не попадают внутрь.
|
||||
→ Решение: `docker cp` для копирования файлов прямо в работающий контейнер, затем restart.
|
||||
→ Урок: при следующем деплое либо добавить bind-mount в docker-compose.yml, либо делать `docker compose build && docker compose up -d`.
|
||||
|
||||
## Следующий шаг
|
||||
Для постоянного решения — добавить bind-mount в docker-compose.yml:
|
||||
```yaml
|
||||
volumes:
|
||||
- /home/slin/enduro-trails/data:/data
|
||||
- /home/slin/enduro-trails/prototype/app.py:/app/app.py
|
||||
- /home/slin/enduro-trails/prototype/static:/app/static
|
||||
```
|
||||
Тогда деплой = просто скопировать файл на хост + `docker compose restart`.
|
||||
Reference in New Issue
Block a user