diff options
Diffstat (limited to 'app/backends/audiocpp/build.py')
| -rw-r--r-- | app/backends/audiocpp/build.py | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/app/backends/audiocpp/build.py b/app/backends/audiocpp/build.py index e3536cf..36c304c 100644 --- a/app/backends/audiocpp/build.py +++ b/app/backends/audiocpp/build.py @@ -59,7 +59,11 @@ def update(*, emit=None, cancel=None) -> int: (a ``prebuilt.json`` marker next to the binary, see ``backends.audiocpp.prebuilt``) take a different route: they skip the git update and rebuild entirely and instead re-download when upstream - published a newer release (see ``_update_prebuilt``). Source-built + published a newer release (see ``_update_prebuilt``) — and when that + re-download fails (rate limit, offline), the same source-build route a + source-built checkout uses runs instead, so 'Update Backends' still + gets current by whatever means work; the installed binary is only + replaced on success and keeps working meanwhile. Source-built checkouts keep the original flow — phases: stop server / git update / rebuild — CANCEL is honored between phases only, so a started phase always completes. The git update is a fetch plus hard reset to origin's @@ -78,7 +82,8 @@ def update(*, emit=None, cancel=None) -> int: interrupted (cancelled or failed) earlier rebuild, which leaves the previous binary in place against already-updated sources. An up-to-date checkout with a fresh binary costs one fetch. Returns the - exit code (130 when cancelled before a remaining phase). + exit code (130 when cancelled before a remaining phase, or when a + prebuilt re-download was cancelled). """ # Only stop when a pid file exists: without one this tool never # started the server, so the "not started by this tool" notice would @@ -92,8 +97,19 @@ def update(*, emit=None, cancel=None) -> int: print("[INFO] No audio.cpp checkout to update.") return 0 backend = _rebuild_backend(checkout) + fell_back = False if _prebuilt.installed_release(checkout, backend) is not None: - return _update_prebuilt(checkout, backend, emit=emit, cancel=cancel) + rc = _update_prebuilt(checkout, backend, emit=emit, cancel=cancel) + if rc == 0 or rc == 130: + return rc + # The re-download failed (the usual cause is GitHub's API rate + # limit): the installed binary was left in place and keeps + # working — recover in place like the install paths do, by + # building from source instead. + print(f"[WARNING] prebuilt update failed (exit {rc}); the installed " + "audiocpp_server was left in place — falling back to a " + "source build...") + fell_back = True head_before = common.git_head(checkout) rc = common.git_update(checkout, emit=emit, cancel=cancel) if rc != 0: @@ -113,6 +129,8 @@ def update(*, emit=None, cancel=None) -> int: moved=head_after not in (None, head_before)): print(f"[OK] {checkout} is already at origin's HEAD with an " "up-to-date audiocpp_server.") + if fell_back: + _drop_prebuilt_marker(checkout, backend) return 0 if head_after in (None, head_before): print(f"[INFO] audiocpp_server on disk is older than the " @@ -130,9 +148,29 @@ def update(*, emit=None, cancel=None) -> int: "retry the rebuild.") else: print("[OK] rebuild complete.") + if fell_back: + _drop_prebuilt_marker(checkout, backend) return build_rc +def _drop_prebuilt_marker(checkout: Path, backend: Optional[str]) -> None: + """Remove the prebuilt.json marker after a fallback source build. + + The fallback replaced (or matched) the downloaded binary with a + source build, so the marker's "this build directory holds release + <tag>" claim is stale — keeping it would make the next update + re-download over the freshly built binary. Best-effort: a marker + that cannot be removed only means the next update re-downloads. + """ + marker = _prebuilt.marker_path(checkout, backend) + if marker is None: + return + try: + marker.unlink(missing_ok=True) + except OSError: + pass + + def _update_prebuilt(checkout: Path, backend: Optional[str], *, emit=None, cancel=None) -> int: """The update route for a prebuilt (release-downloaded) install. @@ -144,8 +182,10 @@ def _update_prebuilt(checkout: Path, backend: Optional[str], *, re-download itself, for the checksum digests. The recorded/detected backend selects the asset, mirroring what was originally installed. A GitHub outage is not fatal — the installed binary keeps working. - Returns the install exit code (0 when already current or when the - check could not run). + Returns 0 when already current or when the check could not run; a + failed re-download returns its exit code and ``update()`` falls back + to a source build (a cancelled download, 130, aborts without + falling back). """ marker = _prebuilt.installed_release(checkout, backend) tag = _prebuilt.resolve_latest_tag() @@ -166,11 +206,6 @@ def _update_prebuilt(checkout: Path, backend: Optional[str], *, cancel=cancel) if rc == 0: print(f"[OK] audiocpp_server updated to {tag}.") - else: - print(f"[WARNING] prebuilt update failed (exit {rc}); the " - "installed audiocpp_server was left in place. Retry " - "'Update Backends' later, or build from source with " - "'Build audio.cpp Server'.") return rc |
