mirror of
https://github.com/henrygd/beszel.git
synced 2026-09-25 02:47:46 +02:00
fix: prevent WebSocket reconnect loops on slow agent collections (#2294)
The hub waited only 5s (the request manager default) for stats over WebSocket and closed the connection on any error. On hosts where `zpool list` stalls (seen on Proxmox, up to its 10s timeout), collection exceeded that limit, so the hub sent a close (code 1000) and the agent reconnected. The refresh ran every other cycle, which caused a disconnect roughly every 2 minutes. Hub: - Wait up to 30s for WebSocket stats responses. - Keep the connection open when a stats request times out; only close it (and fall back to SSH) for other errors. Agent: - After the first collection, refresh `zpool list` pool stats and `zfs list` dataset usage in the background and serve cached values meanwhile, so a hung utility cannot delay the stats response.
This commit is contained in:
@@ -518,3 +518,31 @@ func TestBtrfsPoolIdentities(t *testing.T) {
|
||||
assert.Equal(t, first, zm.GetDetail(true).Pools[1].Name)
|
||||
assert.Equal(t, "renamed", zm.GetDetail(true).Pools[1].DisplayName)
|
||||
}
|
||||
|
||||
func TestStaleUtilityCachesRefreshInBackground(t *testing.T) {
|
||||
release := make(chan struct{})
|
||||
b := &poolBackend{name: "zfs"}
|
||||
b.poolStatsFn = func() ([]zfs.PoolStat, error) {
|
||||
<-release
|
||||
return []zfs.PoolStat{{Name: "new"}}, nil
|
||||
}
|
||||
b.datasetsFn = func() ([]zfs.Dataset, error) {
|
||||
<-release
|
||||
return []zfs.Dataset{{Name: "new", Mountpoint: "/new"}}, nil
|
||||
}
|
||||
b.poolData = []zfs.PoolStat{{Name: "old"}}
|
||||
b.lastPoolStats = time.Now().Add(-2 * poolStatsRefreshInterval)
|
||||
b.datasetUsage = map[string]zfsDatasetUsage{"/old": {}}
|
||||
b.lastUsageRefresh = time.Now().Add(-2 * datasetUsageRefreshInterval)
|
||||
|
||||
// A hung utility must not block collection; cached data is served meanwhile.
|
||||
for range 2 {
|
||||
assert.Equal(t, "old", b.poolStats()[0].Name)
|
||||
assert.Contains(t, b.refreshDatasetUsage(), "/old")
|
||||
}
|
||||
|
||||
close(release)
|
||||
require.Eventually(t, func() bool {
|
||||
return b.poolStats()[0].Name == "new" && b.refreshDatasetUsage()["/new"] == zfsDatasetUsage{}
|
||||
}, time.Second, time.Millisecond)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user