proxy_fallback.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. package service
  2. import "time"
  3. // ResolveProxyFallbackTarget 计算一个过期代理 start 应把账号改投到哪里。
  4. // 返回 (targetID, change):
  5. // - change=false:不改动账号(mode=none,或链路成环/无解的兜底)
  6. // - change=true, targetID=nil:改投为直连
  7. // - change=true, targetID!=nil:改投到该备用代理 id
  8. //
  9. // byID 是「全部代理」的快照(id -> Proxy),now 为判定基准时间。
  10. func ResolveProxyFallbackTarget(start Proxy, byID map[int64]Proxy, now time.Time) (*int64, bool) {
  11. switch start.FallbackMode {
  12. case FallbackModeDirect:
  13. return nil, true
  14. case FallbackModeProxy:
  15. visited := map[int64]struct{}{start.ID: {}}
  16. curID := start.BackupProxyID
  17. for {
  18. if curID == nil {
  19. return nil, false
  20. }
  21. if _, seen := visited[*curID]; seen {
  22. return nil, false
  23. }
  24. p, ok := byID[*curID]
  25. if !ok {
  26. return nil, false
  27. }
  28. if !(&p).IsExpired(now) && p.Status != StatusExpired {
  29. id := p.ID
  30. return &id, true
  31. }
  32. visited[*curID] = struct{}{}
  33. switch p.FallbackMode {
  34. case FallbackModeDirect:
  35. return nil, true
  36. case FallbackModeProxy:
  37. curID = p.BackupProxyID
  38. default:
  39. return nil, false
  40. }
  41. }
  42. default:
  43. return nil, false
  44. }
  45. }