Issues / #670
#670 Keeping the old engine when an update succeeds but turns out bad - and a question about where the web app should call it
closed · @demetree · 2 comentarios · En GitHub
Setup & installServer & APIWindows
Descripción
**Title:** Keeping the old engine when an update succeeds but turns out bad — and a question about where the web app should call it
Two things, the second optional. I have a prototype of the first in #645 if you want it.
## 1. A successful engine update has no way back
`setup.py` is careful about a *failed* update: `update_installed_engine()` keeps the installed engine
and starts that instead when the download or the arch check does not work out. That is the right
behaviour, and I did not want to touch it.
The gap is the other direction. In `get_prebuilt()`, the replacement is:
```python
for p in tmp.iterdir():
dst = eng / p.name
if dst.exists():
shutil.rmtree(dst) if dst.is_dir() else dst.unlink()
p.replace(dst)
```
The installed file is deleted and then replaced. If the new engine then turns out to be bad — a crash
only on your card, a regression you hit an hour later, a config that behaves differently — there is no
copy of the old one. The only recovery is re-downloading a release zip by hand.
Two smaller things in the same area:
- That loop is not all-or-nothing. If it dies partway through, the engine directory holds a mix of old
and new files.
- `update_install` prints `Strata is updated (engine 0.1.38)` to the console and nothing else. UPDATE.bat
closes, so afterwards there is nothing to ask — no version before/after, no list of what changed.
I measured what a copy would cost, on the current release (v0.1.38, `strata-windows-x64.zip`,
124,279,645 bytes as published): `strata.exe` is 113,479,168 bytes and `strata-vision.exe` is
108,195,328 uncompressed, so one generation kept on disk is 221,674,697 bytes — 211 MiB. Worth saying
plainly, because it is the whole argument against keeping more than one.
**Would you take a backup?** Concretely: copy `engine/` to `engine/.previous` (or a timestamped sibling)
before the replace loop, keep one generation, and say on a start which version is installed and which is
kept. That is small and self-contained. My prototype does this, if you would rather look at working code
than a description — but it is a much smaller change than what is in #645.
## 2. Should the web app be able to update the engine at all?
Not asking for it. Asking whether it is wanted, because I could not work out where you would want it to
live, and I would rather not guess.
I had assumed updating was manual — download the release zip, replace the files. It is not:
`update_installed_engine()` runs on every `START-HERE.bat` (setup.py:3042, 3058), and `UPDATE.bat` /
`update.sh` (#475) does it deliberately without starting the model. And `get_prebuilt()` already does
what I thought was the clever part — it unpacks to `engine/_unpack` and checks the *release's* own
`archs` against your GPU before installing, falling back to compiling. So "update the engine" is solved,
twice, and better than my first attempt at it.
What genuinely is missing is doing it from the page the user is already on, and seeing it happen: the
engine is a 124 MB download, the model must be stopped first (the server knows whether it is loaded, and
whether a request is in flight — `unload()` already refuses with "busy"), and a console window that
closes is not much of a progress display.
Three answers I can see:
- **(a) Reuse it.** The web route shells out to `setup.py --update` and relays its output. Nothing to
keep in sync, no second arch rule. Cost: a console process from the server, and progress means parsing
text that is not a contract.
- **(b) Keep it in `serve/`,** as #645 does. Real progress, no shelling out, and the server knows the
state that matters. Cost: a second implementation of download-verify-replace, and a second copy of the
arch rule.
- **(c) Neither** — the web app shows the installed version and whether a newer release exists, and
leaves updating itself to UPDATE.bat. A few dozen lines, no duplication, but no progress and no backup.
If you have a preference I will reshape #645 to match rather than defend the shape it happens to be in.
If the answer is (c), most of #645 should be deleted, which I am fine with.
## 3. Two small ones, separate from the above
- **`BUILD.json` with a BOM.** `json.loads(path.read_text())` at `serve/server.py:322` raises on the
three BOM bytes, so an engine whose `BUILD.json` was saved by a Windows editor, or by PowerShell's
`Set-Content -Encoding utf8`, reports no version — which the About tab then shows as "built from
source". One line: `encoding="utf-8-sig"`, as `setup.py` already does for some of its configs. I have
deliberately left it out of #645 rather than smuggle it in; happy to send it as its own small PR.
- **No checksums on the release.** Neither the assets nor `BUILD.json` carries one, so there is no way to
confirm a downloaded engine is the published one — only that it is not truncated and that it starts.
A `sha256` alongside each asset would close that. I did not include the release-side change, because
publishing a hash nothing checks is worse than none; say the word and I will write it.En el sitio
Enlaces a install, modelos, releases.