You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Sequential retrieve mode can deliver a previous study's instances to the next retrieve (no C-CANCEL, lock released on stream end) #71
In wado-rs.mode: sequential, a retrieve can receive another study's instances (possibly another patient's). Code refs are at v3.0.2 (f89009d).
Sequential subscribes by AE only, (AE, None) (src/backend/dimse/wado.rs:176-179).
The C-MOVE is never cancelled at the peer when a retrieve ends early. There is no C-CANCEL in src/backend/dimse/cmove/movescu.rs:27-80.
The per-AE lock and the subscription are released as soon as the HTTP stream is dropped (src/backend/dimse/cmove/mediator.rs:134-145).
After a client disconnect or a read timeout, the peer keeps pushing the old study. The next sequential retrieve for that AE subscribes again and yields every instance it receives, unfiltered (wado.rs:208-210).
Proposed fix
Drop, and count in a log, received instances whose StudyInstanceUID does not match the request. Also check SeriesInstanceUID / SOPInstanceUID for series and instance retrieves. Do it in retrieve_instances, in all modes.
And/or send a C-CANCEL for the move when the stream is dropped.
This matters for peers that do not send Move Originator Message ID (0000,1031), which forces sequential mode.
Found and drafted with an AI agent (Claude), checked against the source.
Follow-up proposal. It also removes sequential mode's one-retrieve-per-AE bottleneck. Code refs at v3.0.2.
In sequential mode, key subscriptions by (AE, StudyInstanceUID) instead of (AE, None). Route each received C-STORE by the StudyInstanceUID in its dataset; the SCP already has the dataset before it publishes (storescp.rs:167-181).
Instances of another study can no longer reach a retrieve, which closes this issue.
Retrieves of different studies on one AE can run concurrently. Today the lock is one per AE (mediator.rs:35-44, :62).
The same study requested twice at once needs a per-(AE, study) lock, because callbacks.insert overwrites an existing topic (mediator.rs:68). A straggler from an abandoned retrieve can then only land in a later retrieve of the same study; dedupe those by SOPInstanceUID.
Instances without a StudyInstanceUID: drop them.
C-CANCEL on stream drop is still worth adding, to stop the orphaned push.
Drafted with an AI agent (Claude), checked against the v3.0.2 source.
Activity
alexluft commentedon Sep 25, 2026
Follow-up proposal. It also removes sequential mode's one-retrieve-per-AE bottleneck. Code refs at v3.0.2.
In sequential mode, key subscriptions by (AE, StudyInstanceUID) instead of
(AE, None). Route each received C-STORE by the StudyInstanceUID in its dataset; the SCP already has the dataset before it publishes (storescp.rs:167-181).mediator.rs:35-44,:62).callbacks.insertoverwrites an existing topic (mediator.rs:68). A straggler from an abandoned retrieve can then only land in a later retrieve of the same study; dedupe those by SOPInstanceUID.C-CANCEL on stream drop is still worth adding, to stop the orphaned push.
Drafted with an AI agent (Claude), checked against the v3.0.2 source.
alexluft commentedon Sep 27, 2026
PR with the study-keyed fix proposed above: #72.
Posted with an AI agent (Claude).