Skip to content

Commit

Permalink
transport: OpenShardConn, retry only when source port is unavailable …
Browse files Browse the repository at this point in the history
…for use

Fixes #281
  • Loading branch information
Kulezi committed Sep 23, 2022
1 parent d33e176 commit 31b0e68
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions transport/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strconv"
"strings"
"sync"
"syscall"
"time"
"unicode"

Expand Down Expand Up @@ -377,6 +378,17 @@ const (
comprBufferSize = 64 * 1024 // 64 Kb
)

/*
Checks if this error indicates that a chosen source port/address cannot be bound.
This is caused by one of the following:
- The source address is already used by another socket,
- The source address is reserved and the process does not have sufficient privileges to use it.
*/
func isAddrUnavailableForUseErr(err error) bool {
return errors.Is(err, syscall.EADDRINUSE) || errors.Is(err, syscall.EPERM)
}

// OpenShardConn opens connection mapped to a specific shard on Scylla node.
func OpenShardConn(ctx context.Context, addr string, si ShardInfo, cfg ConnConfig) (*Conn, error) {
it := ShardPortIterator(si)
Expand All @@ -385,12 +397,16 @@ func OpenShardConn(ctx context.Context, addr string, si ShardInfo, cfg ConnConfi
conn, err := OpenLocalPortConn(ctx, addr, it(), cfg)
if err != nil {
cfg.Logger.Infof("%s dial error: %s (try %d/%d)", addr, err, i, maxTries)
continue
if isAddrUnavailableForUseErr(err) {
continue
}

return nil, fmt.Errorf("failed to open connection to shard: %w", err)
}
return conn, nil
}

return nil, fmt.Errorf("failed to open connection on shard %d: all local ports are busy", si.Shard)
return nil, fmt.Errorf("failed to open connection on shard %d: all local ports are unavailable for use", si.Shard)
}

// OpenLocalPortConn opens connection on a given local port.
Expand Down

0 comments on commit 31b0e68

Please sign in to comment.