Skip to content

Commit 1bdbcd3

Browse files
authored
Merge pull request #819 from openziti/leak-fixes
leak fixes
2 parents cfa350b + 09b519f commit 1bdbcd3

File tree

5 files changed

+49
-39
lines changed

5 files changed

+49
-39
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# Release notes 1.2.9
2+
3+
## Issues Fixed and Dependency Updates
4+
5+
* github.com/openziti/sdk-golang: [v1.2.8 -> v1.2.9](https://github.com/openziti/sdk-golang/compare/v1.2.8...v1.2.9)
6+
* [Issue #818](https://github.com/openziti/sdk-golang/issues/818) - Full re-auth should not clear services list, as that breaks the on-change logic
7+
* [Issue #817](https://github.com/openziti/sdk-golang/issues/817) - goroutines can get stuck when iterating over randomized HA controller list
8+
19
# Release notes 1.2.8
210

311
## Issues Fixed and Dependency Updates

edge-apis/pool.go

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@
1717
package edge_apis
1818

1919
import (
20-
"github.com/go-openapi/runtime"
21-
"github.com/michaelquigley/pfxlog"
22-
cmap "github.com/orcaman/concurrent-map/v2"
23-
errors "github.com/pkg/errors"
2420
"math/rand/v2"
2521
"net"
2622
"net/url"
2723
"slices"
2824
"sync/atomic"
2925
"time"
26+
27+
"github.com/go-openapi/runtime"
28+
"github.com/michaelquigley/pfxlog"
29+
cmap "github.com/orcaman/concurrent-map/v2"
30+
errors "github.com/pkg/errors"
3031
)
3132

3233
type ApiClientTransport struct {
@@ -151,23 +152,14 @@ func (c *ClientTransportPoolRandom) TryTransportsForOp(operation *runtime.Client
151152
return result, err
152153
}
153154

154-
func (c *ClientTransportPoolRandom) IterateRandomTransport() <-chan *ApiClientTransport {
155-
var transportsToTry []*cmap.Tuple[string, *ApiClientTransport]
156-
for tpl := range c.pool.IterBuffered() {
157-
transportsToTry = append(transportsToTry, &tpl)
158-
}
159-
160-
ch := make(chan *ApiClientTransport, len(transportsToTry))
161-
162-
go func() {
163-
for len(transportsToTry) > 0 {
164-
var transportTpl *cmap.Tuple[string, *ApiClientTransport]
165-
transportTpl, transportsToTry = selectAndRemoveRandom(transportsToTry, nil)
166-
ch <- transportTpl.Val
167-
}
168-
}()
155+
func (c *ClientTransportPoolRandom) IterateRandomTransport() []*ApiClientTransport {
156+
var result []*ApiClientTransport
157+
c.pool.IterCb(func(_ string, v *ApiClientTransport) {
158+
result = append(result, v)
159+
})
169160

170-
return ch
161+
Randomize(result)
162+
return result
171163
}
172164

173165
func (c *ClientTransportPoolRandom) TryTransportForF(cb func(*ApiClientTransport) (any, error)) (any, error) {
@@ -200,12 +192,12 @@ func (c *ClientTransportPoolRandom) TryTransportForF(cb func(*ApiClientTransport
200192
// either no active or active failed, lets start trying them at random
201193
pfxlog.Logger().Debug("trying random transports from pool")
202194

203-
ch := c.IterateRandomTransport()
195+
transports := c.IterateRandomTransport()
204196

205197
var lastResult any
206198
lastErr := errors.New("no transports to try, active transport already failed or was nil") //default err should never be returned
207199
attempts := 0
208-
for transport := range ch {
200+
for _, transport := range transports {
209201
// skip the already attempted active key
210202
if activeKey != "" && transport.ApiUrl.String() == activeKey {
211203
continue
@@ -258,6 +250,16 @@ func errorIndicatesControllerSwap(err error) bool {
258250
return false
259251
}
260252

253+
func Randomize[T any](s []T) {
254+
for i := 0; i < len(s); i++ {
255+
idx := rand.IntN(len(s))
256+
e1 := s[i]
257+
e2 := s[idx]
258+
s[i] = e2
259+
s[idx] = e1
260+
}
261+
}
262+
261263
func selectAndRemoveRandom[T any](slice []T, zero T) (selected T, modifiedSlice []T) {
262264
if len(slice) == 0 {
263265
return zero, slice

ziti/contexts.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ func NewContextWithOpts(cfg *Config, options *Options) (Context, error) {
9292
routerProxy: cfg.RouterProxy,
9393
maxDefaultConnections: int(cfg.MaxDefaultConnections),
9494
maxControlConnections: int(cfg.MaxControlConnections),
95+
services: cmap.New[*rest_model.ServiceDetail](),
96+
sessions: cmap.New[*rest_model.SessionDetail](),
97+
intercepts: cmap.New[*edge.InterceptV1Config](),
9598
}
9699

97100
if newContext.maxDefaultConnections < 1 {

ziti/sdkinfo/build_info.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ziti/ziti.go

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,6 @@ func (context *ContextImpl) processServiceUpdates(services []*rest_model.Service
545545
context.Emit(EventServiceRemoved, svc)
546546

547547
context.deleteServiceSessions(*svc.ID)
548-
549548
}
550549
})
551550

@@ -603,7 +602,9 @@ func (context *ContextImpl) processServiceAddOrUpdated(s *rest_model.ServiceDeta
603602
})
604603

605604
if isChange {
606-
context.Emit(EventServiceChanged, s)
605+
if valuesDiffer {
606+
context.Emit(EventServiceChanged, s)
607+
}
607608
} else {
608609
context.Emit(EventServiceAdded, s)
609610
}
@@ -614,7 +615,6 @@ func (context *ContextImpl) processServiceAddOrUpdated(s *rest_model.ServiceDeta
614615
context.options.OnServiceUpdate(ServiceChanged, s)
615616
}
616617
} else {
617-
context.services.Set(*s.Name, s)
618618
context.options.OnServiceUpdate(ServiceAdded, s)
619619
}
620620
}
@@ -740,17 +740,16 @@ func (context *ContextImpl) refreshServices(forceRefresh, refreshAfterAuth bool)
740740
}
741741

742742
target := &service.ListServicesUnauthorized{}
743-
if errors.As(err, &target) {
744-
log.Info("attempting to re-authenticate")
745-
if authErr := context.Authenticate(); authErr != nil {
746-
log.WithError(authErr).Error("unable to re-authenticate during services refresh")
747-
return err
748-
}
749-
if services, err = context.CtrlClt.GetServices(); err != nil {
750-
return err
751-
}
743+
if !errors.As(err, &target) {
744+
return err
745+
}
752746

753-
} else {
747+
log.Info("attempting to re-authenticate")
748+
if authErr := context.Authenticate(); authErr != nil {
749+
log.WithError(authErr).Error("unable to re-authenticate during services refresh")
750+
return err
751+
}
752+
if services, err = context.CtrlClt.GetServices(); err != nil {
754753
return err
755754
}
756755
}
@@ -955,9 +954,7 @@ func (context *ContextImpl) setUnauthenticated() {
955954

956955
func (context *ContextImpl) authenticate() error {
957956
logrus.Debug("attempting to authenticate")
958-
context.services = cmap.New[*rest_model.ServiceDetail]()
959-
context.sessions = cmap.New[*rest_model.SessionDetail]()
960-
context.intercepts = cmap.New[*edge.InterceptV1Config]()
957+
context.sessions.Clear()
961958

962959
context.setUnauthenticated()
963960

0 commit comments

Comments
 (0)