Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(app-shell-odd): overhaul odd system update (#16486)
Flex robots are capable of updating their own software from the Internet or from USB sticks containing update files. This functionality is handled by the ODD's node side in `app-shell-odd`. It was implemented early in the flex development life cycle before we'd gotten a strong understanding of how everything would work, and was therefore a little scattershot and not really conformant to the way we now think about and structure our code. It also had some unexpected behaviors and was generally a little buggy. This PR refactors `app-shell-odd`'s system update mechanisms, ideally fixing said bugs. ## non-goals ### changing the frontend or the redux interaction patterns this was already a pretty big pr, so I didn't touch these. They probably should be touched, though; sourcing updates from web or from usb is a different thing from sourcing updates from web or from the user's file browser, which is what the UI side and the redux messages are designed to implement, and the concepts don't map terribly well. The redux message flow and semantics should not change in this PR, and this PR doesn't touch any app code ### changing the precedence or user-visible functionality of system updates We still have this idea that - Updates should be presented when an available update is different than the current system version - Updates from USB sticks have higher precedence than updates from the internet, even if the update from the internet has a higher version than the update from the USB stick - If multiple updates from sources of the same precedence are available (i.e., a USB stick with multiple update files is connected) then the update with the highest version takes precedence Changing this would require changing the frontend to have more than a "press a button to start an available update" type of flow, and require changing the redux messages. ## goals ### make the code easier to reason about The code was split sort of weirdly between a single ts file and a module of ts files; code to handle USB updates was scattered around the code to handle internet updates; it was generally a tough assignment to figure out what would happen when user actions are taken or redux messages are sent. Make it easier to understand ### make the code more robust The code didn't really uniformly handle errors or handle errors in the same way in multiple places; this is pretty much guaranteed because the code didn't really have tests. ## changes - move all the system update code into `system-update` - separate the code strongly by layer. the layer that handles the redux messages is in `system-update/handler.ts`, and it imports functions from lower levels in the `from-usb` and `from-web` modules. - separate the code strongly by source. all code dealing with updates from the web is in the `system-updates/from-web` moduels; the code dealing with updates from usb is in `system-updates/from-usb`. Each module presents a closure with a well-defined interface that the handler can use. - remove global mutable state in favor of closed-over mutable state for better testability - add tests, for everything (this is where the size of the diff is from) ## review requests - this is a pr that is mostly motivated by readability and robustness, so opinions on how readable and robust the code is are very welcome and needed - is the behavior correct from the description above? ## reviewing This ended up being a pretty big PR, sorry! I think a good way to approach looking at is to structure into the mostly-separate changes, which only affect each other implicitly: - the new cancellation mechanics in HTTP as its own thing - the action distribution changes in `main` - the `app.getPath()` changes in `main` and in `config` - the mechanics of `system-update/handler` first, then the two update providers underneath; the logic here is separated into "conveying the status of updates" in `handler.ts` and "getting updates" in the providers - the usb device sensing changes, which handle mass storage devices that are like `/dev/sda` but mounted at `/media/VOLUMENAME-sda` and fix excessive timeouts in the recursive enumeration ## testing this needs to be tested on a flex (conveniently, the OT-2 doesn't run this code). things that should be tested are - [x] when the robot is connected to the internet on an update channel that has an available update that is higher than the current robot version, does the system download, present, and apply the update - [x] when the robot is connected to the internet on an update channel that has an available update that is lower than or the same as the current robot version, does the system download but not present the update - [x] when the robot is connected to the internet on an update channel that has an available update, then disconnected after downloading the available update, does the system present and apply the update - [x] when the robot is disconnected from the internet while downloading an available update, does the system not present the update - [x] when you change the update channel, does the presented update get properly cleared and re-queried, including - [x] changing from a channel with an update to a channel with a different update - [x] changing from a channel with an update to a channel without an update - [x] changing from a channel without an update to a channel with an update - [x] when you plug in a usb stick with an update, it gets detected, presented, and applied - [x] including when an update is available from the internet - [x] including when the internet update is of a higher version than the usb update - [x] including when there are multiple updates on the usb stick - [x] including when the update on the usb stick is a lower version than the current version of the robot Closes RQA-3060
- Loading branch information