@@ -29,35 +29,53 @@ import (
2929 "time"
3030)
3131
32+ // ApiClientTransport wraps a runtime.ClientTransport with its associated API URL,
33+ // enabling tracking of which controller endpoint a transport communicates with.
3234type ApiClientTransport struct {
3335 runtime.ClientTransport
3436 ApiUrl * url.URL
3537}
3638
37- // ClientTransportPool abstracts the concept of multiple ` runtime.ClientTransport` (openapi interface) representing one
38- // target OpenZiti network. In situations where controllers are running in HA mode (multiple controllers) this
39- // interface can attempt to try a different controller during outages or partitioning .
39+ // ClientTransportPool manages multiple runtime.ClientTransport instances representing
40+ // different controller endpoints in a high-availability OpenZiti network. It provides
41+ // automatic failover capabilities when individual controllers become unavailable .
4042type ClientTransportPool interface {
4143 runtime.ClientTransport
4244
45+ // Add registers a new transport for the specified API URL.
4346 Add (apiUrl * url.URL , transport runtime.ClientTransport )
47+
48+ // Remove unregisters the transport for the specified API URL.
4449 Remove (apiUrl * url.URL )
4550
51+ // GetActiveTransport returns the currently selected transport.
4652 GetActiveTransport () * ApiClientTransport
53+
54+ // SetActiveTransport designates which transport to use for subsequent operations.
4755 SetActiveTransport (* ApiClientTransport )
56+
57+ // GetApiUrls returns all registered API URLs.
4858 GetApiUrls () []* url.URL
59+
60+ // IterateTransportsRandomly provides a channel for iterating through available transports
61+ // in random order.
4962 IterateTransportsRandomly () chan <- * ApiClientTransport
5063
64+ // TryTransportsForOp attempts to execute an operation, trying different transports
65+ // on connection failures.
5166 TryTransportsForOp (operation * runtime.ClientOperation ) (any , error )
67+
68+ // TryTransportForF executes a callback function, trying different transports
69+ // on connection failures.
5270 TryTransportForF (cb func (* ApiClientTransport ) (any , error )) (any , error )
5371}
5472
5573var _ runtime.ClientTransport = (ClientTransportPool )(nil )
5674var _ ClientTransportPool = (* ClientTransportPoolRandom )(nil )
5775
58- // ClientTransportPoolRandom selects a client transport (controller) at random until it is unreachable. Controllers
59- // are tried at random until a controller is reached. The newly connected controller is set for use on future requests
60- // until is too becomes unreachable.
76+ // ClientTransportPoolRandom implements a randomized failover strategy for controller selection.
77+ // It maintains an active transport and switches to randomly selected alternatives when the active
78+ // transport becomes unreachable.
6179type ClientTransportPoolRandom struct {
6280 pool cmap.ConcurrentMap [string , * ApiClientTransport ]
6381 current atomic.Pointer [ApiClientTransport ]
@@ -106,6 +124,7 @@ func (c *ClientTransportPoolRandom) GetActiveTransport() *ApiClientTransport {
106124 return active
107125}
108126
127+ // GetApiClientTransports returns a snapshot of all registered transports.
109128func (c * ClientTransportPoolRandom ) GetApiClientTransports () []* ApiClientTransport {
110129 var result []* ApiClientTransport
111130
@@ -116,6 +135,7 @@ func (c *ClientTransportPoolRandom) GetApiClientTransports() []*ApiClientTranspo
116135 return result
117136}
118137
138+ // NewClientTransportPoolRandom creates a new transport pool with randomized failover.
119139func NewClientTransportPoolRandom () * ClientTransportPoolRandom {
120140 return & ClientTransportPoolRandom {
121141 pool : cmap .New [* ApiClientTransport ](),
@@ -151,6 +171,7 @@ func (c *ClientTransportPoolRandom) TryTransportsForOp(operation *runtime.Client
151171 return result , err
152172}
153173
174+ // IterateRandomTransport returns a channel that yields all transports in random order.
154175func (c * ClientTransportPoolRandom ) IterateRandomTransport () <- chan * ApiClientTransport {
155176 var transportsToTry []* cmap.Tuple [string , * ApiClientTransport ]
156177 for tpl := range c .pool .IterBuffered () {
@@ -223,6 +244,7 @@ func (c *ClientTransportPoolRandom) TryTransportForF(cb func(*ApiClientTransport
223244 return lastResult , lastErr
224245}
225246
247+ // AnyTransport returns a randomly selected transport from the pool, or nil if empty.
226248func (c * ClientTransportPoolRandom ) AnyTransport () * ApiClientTransport {
227249 transportBuffer := c .pool .Items ()
228250 var keys []string
@@ -245,6 +267,8 @@ var _ ClientTransportPool = (*ClientTransportPoolRandom)(nil)
245267
246268var opError = & net.OpError {}
247269
270+ // errorIndicatesControllerSwap determines whether an error suggests the need to
271+ // switch to a different controller endpoint.
248272func errorIndicatesControllerSwap (err error ) bool {
249273 pfxlog .Logger ().WithError (err ).Debugf ("checking for network errror on type (%T) and its wrapped errors" , err )
250274
@@ -258,6 +282,8 @@ func errorIndicatesControllerSwap(err error) bool {
258282 return false
259283}
260284
285+ // selectAndRemoveRandom randomly selects an element from the slice and returns both
286+ // the selected element and a new slice with that element removed.
261287func selectAndRemoveRandom [T any ](slice []T , zero T ) (selected T , modifiedSlice []T ) {
262288 if len (slice ) == 0 {
263289 return zero , slice
0 commit comments