Skip to content

editoast: fix work_schedules pagination by ordering on id instead of obj_id - #18749

Merged
elise-chin merged 2 commits into
devfrom
ecn/fix-work-schedules-pagination
Sep 23, 2026
Merged

elise-chin merged 2 commits into
devfrom
ecn/fix-work-schedules-pagination

Conversation

@elise-chin

@elise-chin elise-chin commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #16277
Fixes #16270

Description

WorkSchedule::OBJ_ID is not unique: a work schedule spanning several days (e.g. a multi-night work) is represented as several rows sharing the same obj_id and track ranges, but with distinct id, start_date and end_date. Ordering by obj_id therefore sorts the column with ties, and Postgres gives no guarantee that row order is consistent across queries.

This caused two bugs on GET /work_schedules/group/{id}:

  1. Rows tied on obj_id could be ordered differently between two consecutive queries, so a row could appear on two consecutive results (duplicate) or be skipped entirely.
  2. On the last (partial) page, it causes PaginationStats::new's consistency assertion to panic, and surface as a 502 error. I suppose because the cumulative count no longer add up to total_count.

Fix: order by WorkSchedule::ID instead of OBJ_ID, same as TrainSchedule already does.

Test

To reproduce on dev branch

  • Start osrd
  • Add this code snippet to count duplicates in download-work-schedules.py
counter = Counter([ws["id"] for ws in work_schedules])
print(counter.most_common(2))
  • Go to core/scripts, and run uv run download-work-schedules.py -u http://localhost:8090/ -g 1 -c -EXAMPLEfooEXAMPLE. You will see this error:
    aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected
    
  • Skip the last page: in core/scripts/common.py, l. 44, remove the +1. Run the same command, and you will see duplicates
    downloading page 29/30
    [(2878, 29), (2918, 29)] -> (id, count)
    

On this branch

  • Start osrd and build editoast
  • Run the same command and you'll see that both bugs are fixed:
    downloading page 30/30
    [(1, 1), (2, 1)] 
    

…obj_id

WorkSchedule::OBJ_ID is not unique: a work schedule spanning several days (e.g. a multi-night work)
is represented as several rows sharing the same obj_id and track ranges, but with
distinct id, start_date and end_date. Ordering by obj_id therefore sorts the column with ties,
and Postgres gives no guarantee that row order is consistent across queries.

This caused two bugs on GET /work_schedules/group/{id}:

1. Rows tied on obj_id could be ordered differently between two consecutive queries,
so a row could appear on two consecutive results (duplicate) or be skipped entirely.

2. On the last (partial) page, it causes PaginationStats::new's consistency assertion
to panic, and surface as a 502 error.
I suppose because the cumulative count no longer add up to total_count.

Fix: order by WorkSchedule::ID instead of OBJ_ID, same as TrainSchedule already does.

Signed-off-by: Elise Chin <tech.git@swively.fr>
@elise-chin elise-chin self-assigned this Sep 23, 2026
@elise-chin
elise-chin requested review from a team as code owners September 23, 2026 13:59
@elise-chin elise-chin added the area:editoast Work on Editoast Service label Sep 23, 2026
@elise-chin
elise-chin requested a review from eckter September 23, 2026 13:59
@github-actions github-actions Bot added area:core Work on Core Service area:front Work on Standard OSRD Interface modules kind:api-change labels Sep 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ API changes

This Pull Request introduces some changes in the API:

  • please own it: notify or even prepare dedicated PR(s) to consumer projects

@eckter eckter left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the fix!

LGTM for the core script, with the removal of the commented code

Comment thread core/scripts/download-work-schedules.py Outdated

@leovalais leovalais left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the fix!

- Skip editoast authentification
- The local gateway_url does not have api in it, so remove it

Signed-off-by: Elise Chin <tech.git@swively.fr>
@elise-chin
elise-chin force-pushed the ecn/fix-work-schedules-pagination branch from 34c1190 to eb172c4 Compare September 23, 2026 14:18
@elise-chin
elise-chin added this pull request to the merge queue Sep 23, 2026
Merged via the queue into dev with commit a9bd611 Sep 23, 2026
75 of 76 checks passed
@elise-chin
elise-chin deleted the ecn/fix-work-schedules-pagination branch September 23, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core Work on Core Service area:editoast Work on Editoast Service area:front Work on Standard OSRD Interface modules kind:api-change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

editoast: work schedule endpoint pagination is (very likely) broken work schedule endpoint returns a 502 on last page

3 participants