mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-06 22:22:08 +03:00
4295ee8a28
A node snapshot that comes back with zero clients for an inbound the hub still has clients on was treated as authoritative: SyncInbound strips every link for that inbound, the orphan sweep marks the now-linkless clients, and ReapSyncOrphans hard-deletes them once the grace period elapses. But a zero-client snapshot is indistinguishable from a degraded node — one that was just deleted, reset, restarted, or answered before its config loaded. On 2026-10-04 this deleted clients across the whole hub when a single node was removed. Treat a zero-client snapshot for an inbound that still has clients as non-authoritative: skip the link rebuild and the orphan sweep for that inbound (the same handling a failed SyncInbound already gets) and wait for a snapshot that carries clients. Removing a node's last client is done from the hub (which updates links and pushes); a node still serving other clients prunes a removed one through the existing partial path. The two orphan tests that drove removal via an empty snapshot now drive it via a partial snapshot (node alive, still serving another client), the authoritative path. New tests in node_degraded_snapshot_test.go cover the guard and its narrowness. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>