mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-13 12:46:36 +08:00
fix(gost): implement failover for multi-node forwarding rules (#12)
When a forwarding rule has multiple backend nodes configured, the first node failure would cause the entire forward to fail instead of trying the next available node. Root causes fixed: - FailFilter skipped filtering when only 1 node remained - hop.Select() bypassed selector for single-node hops - Handlers only attempted one node before giving up Changes: - selector/filter.go: Remove len<=1 early return, always filter failed nodes - hop/hop.go: Remove single-node bypass, add ExcludeNodes context support - ctx/value.go: Add ContextWithExcludeNodes/ExcludeNodesFromContext helpers - handler/forward/local: Add maxRetries config, implement retry loop - handler/forward/remote: Add maxRetries config, implement retry loop - forwarder/sniffer.go: Add retry logic to dial() and dialTLS() Closes #12
This commit is contained in:
@@ -5,8 +5,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/metadata"
|
||||
mdutil "github.com/go-gost/x/metadata/util"
|
||||
"github.com/go-gost/core/selector"
|
||||
mdutil "github.com/go-gost/x/metadata/util"
|
||||
)
|
||||
|
||||
type failFilter[T any] struct {
|
||||
@@ -24,10 +24,11 @@ func FailFilter[T any](maxFails int, timeout time.Duration) selector.Filter[T] {
|
||||
}
|
||||
|
||||
// Filter filters dead objects.
|
||||
// Note: We intentionally do NOT skip filtering when len(vs) <= 1.
|
||||
// This ensures that even a single dead node gets filtered out,
|
||||
// allowing the caller to know that no healthy nodes are available
|
||||
// and potentially trigger failover behavior.
|
||||
func (f *failFilter[T]) Filter(ctx context.Context, vs ...T) []T {
|
||||
if len(vs) <= 1 {
|
||||
return vs
|
||||
}
|
||||
var l []T
|
||||
for _, v := range vs {
|
||||
maxFails := f.maxFails
|
||||
|
||||
Reference in New Issue
Block a user