Waypoints GET refetches every route after each best solution, one at a time, under one lock
Maintainer thường phản hồi trong vòng 1 ngày
@rsynek đang làm issue này rồi.
Từ ngày 5/11/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
Describe the bug
GET /v1/route-plans/{id}/waypoints is slow while a run solves, and the map in the visualization waits for it.
WaypointsServiceImpl on main has three causes:
onBestSolution(WaypointsServiceImpl.java:116) replaces the whole route map of the run. The nextGETfetches every route from the map service again, also the routes whose stops did not change.getWaypoints(WaypointsServiceImpl.java:61) issynchronizedon the bean, so one lock serves all runs. It calls the map service one route at a time, and it holds the lock through the retry delays.runIdsToWaypoints(WaypointsServiceImpl.java:49) never removes a run. It is also the only source of waypoints for a finished run, so memory grows with each run until a restart.
Think of a courier who throws away every drawn route after each new order. Then the courier redraws each route, also the unchanged ones, with the one pen that all couriers share.
Expected behavior
A GET after a best solution fetches only the routes whose stops changed, fetches them in parallel, and does not block the other runs. The service removes a finished run from memory, and a later GET reads the stored waypoints of that run.
Actual behavior
Measured with a fake map service at 150 ms per call, 50 vehicles, and a best solution that changes 5 routes:
| Time | Map service calls | |
|---|---|---|
GET after a best solution |
7,829 ms | 50 |
First GET |
7,877 ms | 50 |
Field Service Routing 2.7.0 in dev mode with a local OSRM (Open Source Routing Machine) server, 45 vehicles with about 175 vehicle shifts (one route for each shift): a GET after a best solution takes 1.13 s to 2.26 s.
To Reproduce
- Start a routing model with a map service, for example Field Service Routing with a local OSRM server.
- Solve a dataset with 45 vehicles or more.
- Call
GET /v1/route-plans/{id}/waypointsevery 2 seconds while the run solves, and log the time of each call.
Each GET after a best solution takes more than a second, and the map service log shows one call per route.
Environment
Timefold Solver Version or Git ref: 2.8.0 (main at 6741d1043)
Output of java -version: not relevant
Output of uname -a or ver: not relevant
Additional information
PR #2723 holds a solution for this bug. I closed it and opened this issue, so the owner of the service module can take over the change. Its approach:
- Keep a route while its stops are equal, and fetch only the changed routes.
- Fetch the missing routes in parallel on a dedicated pool (
timefold.platform.map-service.waypoints-parallelism, default 8), without the global lock. Requests at the same time for the same route share one fetch. - For a viewed run, fetch the changed routes in the background after a best solution, at most one batch at a time for each run.
- Release a run after
SaveWaypointsPostProcessorstores its waypoints, or when the run fails. A laterGETreads the waypoints from storage. A bounded list of released run ids stops a late event from adding a released run again. - Send
FAILEDwith the run id when the run metadata cannot be read. Without this, a failed run is not released:SolverWorker.notifyOnFailurethrows aNullPointerExceptionwhengetMetadatareturns null.
With the change of PR #2723, the same measurement with the fake map service gives 160 ms and 5 calls for a GET after a best solution. The Field Service Routing measurement gives 20 ms to 60 ms.
- Ngôn ngữ chính
- Java
- Star
- 1.8k
- Fork
- 243
- Merge trung bình
- 2 ngày 4 giờ
- Pull request đã merge (30 ngày)
- 46
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của TimefoldAI/timefold-solver
-
component/docs
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
TimefoldAI/timefold-solver#2671 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
process/needs triage
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 12/100
TimefoldAI/timefold-solver#2763 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Docs: Add keywords for search.Có thể đã có người làm @TomCools đã nhận 22 ngày trước. Đang mởcomponent/docs
TimefoldAI/timefold-solver#2762 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
SDK: Waypoints class has not OpenAPI Spec annotations.Có thể đã có người làm @TomCools đã nhận 23 ngày trước. Đang mởcomponent/service
TimefoldAI/timefold-solver#2759 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
component/service
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
TimefoldAI/timefold-solver#2755 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của TimefoldAI/timefold-solver
Issue tương tự
-
getRawTextContent() returns the lines of every page in reverse order (bottom to top) since 4.0.3Đang mở
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 90/100
-
bug subsystem:agent-harness triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
ShaftHQ/SHAFT_ENGINE#7797 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
ARM: Q flag should be stickyĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
NationalSecurityAgency/ghidra#10155 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
area:data coverage
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 67/100
reacher-z/Awesome-CUA#4864 ·
Maintainer thường phản hồi trong vòng 19 ngày
-
bug web-ui
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
jenkinsci/jenkins#27705 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày