@@ -45,19 +45,25 @@ func (sp *ServerPicker) PickServer(parentCtx context.Context) (*Client, error) {
45
45
concurrentLimiter := make (chan struct {}, maxConcurrentServers )
46
46
47
47
log .Debugf ("pick server from list: %v" , sp .ServerURLs .Load ().([]string ))
48
+ go sp .processConnResults (connResultChan , successChan )
48
49
for _ , url := range sp .ServerURLs .Load ().([]string ) {
49
- // todo check if we have a successful connection so we do not need to connect to other servers
50
- concurrentLimiter <- struct {}{}
51
- go func (url string ) {
52
- defer func () {
53
- <- concurrentLimiter
54
- }()
55
- sp .startConnection (parentCtx , connResultChan , url )
56
- }(url )
50
+ select {
51
+ case concurrentLimiter <- struct {}{}:
52
+ go func (url string ) {
53
+ defer func () {
54
+ <- concurrentLimiter
55
+ }()
56
+ sp .startConnection (parentCtx , connResultChan , url )
57
+ }(url )
58
+ case cr , ok := <- successChan :
59
+ if ! ok {
60
+ return nil , errors .New ("failed to connect to any relay server: all attempts failed" )
61
+ }
62
+ log .Infof ("chosen home Relay server: %s with latency %s" , cr .Url , cr .Latency )
63
+ return cr .RelayClient , nil
64
+ }
57
65
}
58
66
59
- go sp .processConnResults (connResultChan , successChan )
60
-
61
67
select {
62
68
case cr , ok := <- successChan :
63
69
if ! ok {
@@ -106,18 +112,8 @@ func (sp *ServerPicker) processConnResults(resultChan chan connResult, successCh
106
112
}
107
113
log .Infof ("connected to Relay server: %s with latency %s" , cr .Url , cr .Latency )
108
114
109
- // Already connected to a lower latency server
110
- if hasSuccess && cr .Latency > bestLatencyResult .Latency {
111
- log .Infof ("closing unnecessary Relay connection to: %s" , cr .Url )
112
- if err := cr .RelayClient .Close (); err != nil {
113
- log .Errorf ("failed to close connection to %s: %v" , cr .Url , err )
114
- }
115
- continue
116
- } else if hasSuccess { // Connected to a higher latency server in bestLatencyResult, disconnect from it
117
- log .Infof ("closing unnecessary Relay connection to: %s" , bestLatencyResult .Url )
118
- if err := bestLatencyResult .RelayClient .Close (); err != nil {
119
- log .Errorf ("failed to close connection to %s: %v" , bestLatencyResult .Url , err )
120
- }
115
+ if hasSuccess {
116
+ cr = lowestLatency (cr , bestLatencyResult )
121
117
}
122
118
123
119
// First successful connection, start a timer to return the result
@@ -138,3 +134,17 @@ func (sp *ServerPicker) processConnResults(resultChan chan connResult, successCh
138
134
}
139
135
close (successChan )
140
136
}
137
+
138
+ func lowestLatency (a , b connResult ) connResult {
139
+ if a .Latency > b .Latency {
140
+ if err := b .RelayClient .Close (); err != nil {
141
+ log .Errorf ("failed to close connection to %s: %v" , b .Url , err )
142
+ }
143
+ return a
144
+ }
145
+
146
+ if err := a .RelayClient .Close (); err != nil {
147
+ log .Errorf ("failed to close connection to %s: %v" , a .Url , err )
148
+ }
149
+ return b
150
+ }
0 commit comments