Refactor and modernize the rescue and archive logic
- The rescuer logic was some of the oldest code in intertube, and used an entirely different model to the rest of the modern code (the track code graph).
- This model basically never gets updated (it's 2 years old!), is hard to generate, and probably wasn't even very good to start with (given it operates at the track code level).
- This replaces the rescuer with a swish new modern one using the toposort
model instead.
- Trains which share a toposort node (order is not paid attention to for now), or which share a leading car number or track code, will be considered for rescue.
- The total list of considered rescues is sorted per-destination, and more likely ones given precedence over less likely ones.
- At the same time, the archival logic was massively overhauled and improved,
to increase performance and sanity.
- We now fetch all trains and their relevant (meta)data (scores and last data point) more efficiently, using pipelining to avoid hundreds of tiny roundtrips.
- This required tweaking some of the redis-raw-* functions to be pipeline compatible.
- We now consider "archive" a distinct set from "rescue", instead of having
the "archived" trains potentially consider a rescue (which was confusing
and silly).
- The XR-specific archiving logic is also now split out properly.
- RESCUE-TRAIN now deletes the source train for you, too.