fix(ui): shorten install/uninstall/update timeouts for async RPCs

With the backend flipped to async-spawn, install/uninstall/update return
immediately with a { status, package_id } envelope. Client timeouts of
45m/11m were a leftover from synchronous handlers and masked real RPC
failures.

Drop all install/uninstall/update RPC timeouts to 15s. Progress and
terminal state still arrive through the live state stream — the RPC
only needs to confirm the spawn was accepted.

Return-type annotations updated in rpc-client.ts and stores/server.ts.
Five direct rpcClient.call sites across Marketplace.vue, Discover.vue,
and MarketplaceAppDetails.vue updated with the shorter timeout.
This commit is contained in:
archipelago
2026-04-23 06:58:02 -04:00
parent 1ad889608f
commit 702b5d64d3
5 changed files with 41 additions and 23 deletions
+23 -13
View File
@@ -521,23 +521,30 @@ class RPCClient {
})
}
async installPackage(id: string, marketplaceUrl: string, version: string): Promise<string> {
async installPackage(
id: string,
marketplaceUrl: string,
version: string,
): Promise<{ status: string; package_id: string }> {
// Backend is async — returns { status: 'installing' } in <1s after
// flipping state and spawning the pull/install pipeline. Progress is
// streamed via WebSocket (install_progress field on the package entry).
return this.call({
method: 'package.install',
params: { id, 'marketplace-url': marketplaceUrl, version },
// 45 min — IndeedHub is 6 images and gitea raw-file throughput is
// ~70 KB/s per image; 15 min was short enough to kill the install
// mid-pull and land the user on a "didn't work" screen while the
// backend kept working in the background.
timeout: 2700000,
timeout: 15000,
})
}
async uninstallPackage(id: string): Promise<void> {
async uninstallPackage(id: string): Promise<{ status: string; package_id: string }> {
// Backend is async — returns { status: 'removing' } immediately after
// flipping state. Graceful stop (up to 600s for bitcoin) and data wipe
// (up to minutes for large chainstate) run in a background task.
// Progress shown via uninstall_stage field on the package entry.
return this.call({
method: 'package.uninstall',
params: { id },
timeout: 660000, // Bitcoin Knots needs up to 600s for UTXO flush
timeout: 15000,
})
}
@@ -545,7 +552,7 @@ class RPCClient {
return this.call({
method: 'package.start',
params: { id },
timeout: 60000,
timeout: 15000,
})
}
@@ -553,7 +560,7 @@ class RPCClient {
return this.call({
method: 'package.stop',
params: { id },
timeout: 120000,
timeout: 15000,
})
}
@@ -561,15 +568,18 @@ class RPCClient {
return this.call({
method: 'package.restart',
params: { id },
timeout: 120000,
timeout: 15000,
})
}
async updatePackage(id: string): Promise<{ status: string }> {
async updatePackage(id: string): Promise<{ status: string; package_id: string }> {
// Backend is async — returns { status: 'updating' } immediately after
// flipping state. Pull / stop / recreate / verify runs in background,
// with rollback-on-failure.
return this.call({
method: 'package.update',
params: { id },
timeout: 660000, // Bitcoin Knots needs up to 600s for graceful shutdown
timeout: 15000,
})
}