Fix Sonar issues

Reduce cognitive complexity
This commit is contained in:
Zoltan Papp
2024-12-02 11:32:05 +01:00
parent f85c52ec70
commit e9d8f7f1ce
3 changed files with 46 additions and 23 deletions

View File

@@ -261,7 +261,8 @@ func (c *Client) Close() error {
} }
func (c *Client) connect() error { func (c *Client) connect() error {
conn, err := dialer.RaceDial(c.log, c.connectionURL, quic.Dialer{}, ws.Dialer{}) rd := dialer.NewRaceDial(c.log, c.connectionURL, quic.Dialer{}, ws.Dialer{})
conn, err := rd.Dial()
if err != nil { if err != nil {
return err return err
} }

View File

@@ -24,44 +24,51 @@ type dialResult struct {
Err error Err error
} }
func RaceDial(log *log.Entry, serverURL string, dialerFns ...DialerFn) (net.Conn, error) { type RaceDial struct {
connChan := make(chan dialResult, len(dialerFns)) log *log.Entry
serverURL string
dialerFns []DialerFn
}
func NewRaceDial(log *log.Entry, serverURL string, dialerFns ...DialerFn) *RaceDial {
return &RaceDial{
log: log,
serverURL: serverURL,
dialerFns: dialerFns,
}
}
func (r *RaceDial) Dial() (net.Conn, error) {
connChan := make(chan dialResult, len(r.dialerFns))
winnerConn := make(chan net.Conn, 1) winnerConn := make(chan net.Conn, 1)
abortCtx, abort := context.WithCancel(context.Background()) abortCtx, abort := context.WithCancel(context.Background())
defer abort() defer abort()
for _, d := range dialerFns { for _, dfn := range r.dialerFns {
go func() { go r.dial(dfn, abortCtx, connChan)
ctx, cancel := context.WithTimeout(abortCtx, connectionTimeout)
defer cancel()
log.Infof("dialing Relay server via %s", d.Protocol())
conn, err := d.Dial(ctx, serverURL)
connChan <- dialResult{Conn: conn, Protocol: d.Protocol(), Err: err}
}()
} }
go func() { go func() {
var hasWinner bool var hasWinner bool
for i := 0; i < len(dialerFns); i++ { for i := 0; i < len(r.dialerFns); i++ {
dr := <-connChan dr := <-connChan
if dr.Err != nil { if dr.Err != nil {
if errors.Is(dr.Err, context.Canceled) { if errors.Is(dr.Err, context.Canceled) {
log.Infof("connection attempt aborted via: %s", dr.Protocol) r.log.Infof("connection attempt aborted via: %s", dr.Protocol)
} else { } else {
log.Errorf("failed to dial via %s: %s", dr.Protocol, dr.Err) r.log.Errorf("failed to dial via %s: %s", dr.Protocol, dr.Err)
} }
continue continue
} }
if hasWinner { if hasWinner {
if cerr := dr.Conn.Close(); cerr != nil { if cerr := dr.Conn.Close(); cerr != nil {
log.Warnf("failed to close connection via %s: %s", dr.Protocol, cerr) r.log.Warnf("failed to close connection via %s: %s", dr.Protocol, cerr)
} }
continue continue
} }
log.Infof("successfully dialed via: %s", dr.Protocol) r.log.Infof("successfully dialed via: %s", dr.Protocol)
abort() abort()
hasWinner = true hasWinner = true
@@ -76,3 +83,12 @@ func RaceDial(log *log.Entry, serverURL string, dialerFns ...DialerFn) (net.Conn
} }
return conn, nil return conn, nil
} }
func (r *RaceDial) dial(dfn DialerFn, abortCtx context.Context, connChan chan dialResult) {
ctx, cancel := context.WithTimeout(abortCtx, connectionTimeout)
defer cancel()
r.log.Infof("dialing Relay server via %s", dfn.Protocol())
conn, err := dfn.Dial(ctx, r.serverURL)
connChan <- dialResult{Conn: conn, Protocol: dfn.Protocol(), Err: err}
}

View File

@@ -77,7 +77,8 @@ func TestRaceDialEmptyDialers(t *testing.T) {
logger := logrus.NewEntry(logrus.New()) logger := logrus.NewEntry(logrus.New())
serverURL := "test.server.com" serverURL := "test.server.com"
conn, err := RaceDial(logger, serverURL) rd := NewRaceDial(logger, serverURL)
conn, err := rd.Dial()
if err == nil { if err == nil {
t.Errorf("Expected an error with empty dialers, got nil") t.Errorf("Expected an error with empty dialers, got nil")
} }
@@ -102,7 +103,8 @@ func TestRaceDialSingleSuccessfulDialer(t *testing.T) {
protocolStr: proto, protocolStr: proto,
} }
conn, err := RaceDial(logger, serverURL, mockDialer) rd := NewRaceDial(logger, serverURL, mockDialer)
conn, err := rd.Dial()
if err != nil { if err != nil {
t.Errorf("Expected no error, got %v", err) t.Errorf("Expected no error, got %v", err)
} }
@@ -134,7 +136,8 @@ func TestRaceDialMultipleDialersWithOneSuccess(t *testing.T) {
protocolStr: "proto2", protocolStr: "proto2",
} }
conn, err := RaceDial(logger, serverURL, mockDialer1, mockDialer2) rd := NewRaceDial(logger, serverURL, mockDialer1, mockDialer2)
conn, err := rd.Dial()
if err != nil { if err != nil {
t.Errorf("Expected no error, got %v", err) t.Errorf("Expected no error, got %v", err)
} }
@@ -156,7 +159,8 @@ func TestRaceDialTimeout(t *testing.T) {
protocolStr: "proto1", protocolStr: "proto1",
} }
conn, err := RaceDial(logger, serverURL, mockDialer) rd := NewRaceDial(logger, serverURL, mockDialer)
conn, err := rd.Dial()
if err == nil { if err == nil {
t.Errorf("Expected an error, got nil") t.Errorf("Expected an error, got nil")
} }
@@ -183,7 +187,8 @@ func TestRaceDialAllDialersFail(t *testing.T) {
protocolStr: "protocol2", protocolStr: "protocol2",
} }
conn, err := RaceDial(logger, serverURL, mockDialer1, mockDialer2) rd := NewRaceDial(logger, serverURL, mockDialer1, mockDialer2)
conn, err := rd.Dial()
if err == nil { if err == nil {
t.Errorf("Expected an error, got nil") t.Errorf("Expected an error, got nil")
} }
@@ -224,7 +229,8 @@ func TestRaceDialFirstSuccessfulDialerWins(t *testing.T) {
protocolStr: proto2, protocolStr: proto2,
} }
conn, err := RaceDial(logger, serverURL, mockDialer1, mockDialer2) rd := NewRaceDial(logger, serverURL, mockDialer1, mockDialer2)
conn, err := rd.Dial()
if err != nil { if err != nil {
t.Errorf("Expected no error, got %v", err) t.Errorf("Expected no error, got %v", err)
} }