Passed
Push — master ( b9a458...e79a13 )
by Tolga
01:29 queued 13s
created

pkg/balancer/picker.go   A

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 39
dl 0
loc 71
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B balancer.*picker.Pick 0 34 7
1
package balancer
2
3
import (
4
	"crypto/rand"
5
	"fmt"
6
	"log"
7
	"math/big"
8
9
	"google.golang.org/grpc/balancer"
10
11
	"github.com/Permify/permify/pkg/consistent"
12
)
13
14
type picker struct {
15
	consistent *consistent.Consistent
16
	width      int
17
}
18
19
// Generate a cryptographically secure random index function with resilient error handling
20
var randomIndex = func(max int) int {
21
	// Ensure max > 0 to avoid issues
22
	if max <= 0 {
23
		log.Println("randomIndex: max value is less than or equal to 0, returning 0 as fallback")
24
		return 0
25
	}
26
27
	// Use crypto/rand to generate a random index
28
	n, err := rand.Int(rand.Reader, big.NewInt(int64(max)))
29
	if err != nil {
30
		// Log the error and return a deterministic fallback value (e.g., 0)
31
		log.Printf("randomIndex: failed to generate a secure random number, returning 0 as fallback: %v", err)
32
		return 0
33
	}
34
35
	return int(n.Int64())
36
}
37
38
func (p *picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
39
	// Safely extract the key from the context
40
	keyValue := info.Ctx.Value(Key)
41
	if keyValue == nil {
42
		return balancer.PickResult{}, fmt.Errorf("context key missing")
43
	}
44
	key, ok := keyValue.([]byte)
45
	if !ok {
46
		return balancer.PickResult{}, fmt.Errorf("context key is not of type []byte")
47
	}
48
49
	// Retrieve the closest N members
50
	members, err := p.consistent.ClosestN(key, p.width)
51
	if err != nil {
52
		return balancer.PickResult{}, fmt.Errorf("failed to get closest members: %v", err)
53
	}
54
	if len(members) == 0 {
55
		return balancer.PickResult{}, fmt.Errorf("no available members")
56
	}
57
58
	// Randomly pick one member if width > 1
59
	index := 0
60
	if p.width > 1 {
61
		index = randomIndex(p.width)
62
	}
63
64
	// Assert the member type
65
	chosen, ok := members[index].(ConsistentMember)
66
	if !ok {
67
		return balancer.PickResult{}, fmt.Errorf("invalid member type: expected subConnMember")
68
	}
69
70
	// Return the chosen connection
71
	return balancer.PickResult{SubConn: chosen.SubConn}, nil
72
}
73