Skip to content

Commit e79a13f

Browse files
authored
Merge pull request #1980 from Permify/feature/distributed-consistent-hashing
refactor: enhance distributed consistent hashing configuration and er…
2 parents b9a458f + 16a2e3a commit e79a13f

File tree

25 files changed

+1227
-850
lines changed

25 files changed

+1227
-850
lines changed

cmd/permify/permify.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package main
33
import (
44
"os"
55

6+
"github.com/cespare/xxhash/v2"
7+
68
"github.com/sercand/kuberesolver/v5"
79
"google.golang.org/grpc/balancer"
810

@@ -12,7 +14,7 @@ import (
1214

1315
func main() {
1416
kuberesolver.RegisterInCluster()
15-
balancer.Register(consistentbalancer.NewConsistentHashBalancerBuilder())
17+
balancer.Register(consistentbalancer.NewBuilder(xxhash.Sum64))
1618

1719
root := cmd.NewRootCommand()
1820

docs/api-reference/apidocs.swagger.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "Permify API",
55
"description": "Permify is an open source authorization service for creating fine-grained and scalable authorization systems.",
6-
"version": "v1.2.7",
6+
"version": "v1.2.8",
77
"contact": {
88
"name": "API Support",
99
"url": "https://github.com/Permify/permify/issues",

docs/api-reference/openapiv2/apidocs.swagger.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "Permify API",
55
"description": "Permify is an open source authorization service for creating fine-grained and scalable authorization systems.",
6-
"version": "v1.2.7",
6+
"version": "v1.2.8",
77
"contact": {
88
"name": "API Support",
99
"url": "https://github.com/Permify/permify/issues",

internal/config/config.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,13 @@ type (
185185
}
186186

187187
Distributed struct {
188-
Enabled bool `mapstructure:"enabled"`
189-
Address string `mapstructure:"address"`
190-
Port string `mapstructure:"port"`
188+
Enabled bool `mapstructure:"enabled"`
189+
Address string `mapstructure:"address"`
190+
Port string `mapstructure:"port"`
191+
PartitionCount int `mapstructure:"partition_count"`
192+
ReplicationFactor int `mapstructure:"replication_factor"`
193+
Load float64 `mapstructure:"load"`
194+
PickerWidth int `mapstructure:"picker_width"`
191195
}
192196
)
193197

internal/engines/balancer/balancer.go

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ package balancer
22

33
import (
44
"context"
5-
"encoding/hex"
65
"fmt"
76
"log/slog"
87
"time"
98

10-
"github.com/cespare/xxhash/v2"
119
"google.golang.org/grpc"
1210
"google.golang.org/grpc/credentials"
1311
"google.golang.org/grpc/credentials/insecure"
@@ -16,15 +14,10 @@ import (
1614
"github.com/Permify/permify/internal/engines"
1715
"github.com/Permify/permify/internal/invoke"
1816
"github.com/Permify/permify/internal/storage"
19-
2017
"github.com/Permify/permify/pkg/balancer"
2118
base "github.com/Permify/permify/pkg/pb/base/v1"
2219
)
2320

24-
var grpcServicePolicy = fmt.Sprintf(`{
25-
"loadBalancingPolicy": "%s"
26-
}`, balancer.Policy)
27-
2821
// Balancer is a wrapper around the balancer hash implementation that
2922
type Balancer struct {
3023
schemaReader storage.SchemaReader
@@ -52,7 +45,7 @@ func NewCheckEngineWithBalancer(
5245
)
5346

5447
// Set up TLS credentials if paths are provided
55-
if srv.TLSConfig.CertPath != "" && srv.TLSConfig.KeyPath != "" {
48+
if srv.TLSConfig.Enabled && srv.TLSConfig.CertPath != "" && srv.TLSConfig.KeyPath != "" {
5649
isSecure = true
5750
creds, err = credentials.NewClientTLSFromFile(srv.TLSConfig.CertPath, srv.TLSConfig.KeyPath)
5851
if err != nil {
@@ -62,10 +55,22 @@ func NewCheckEngineWithBalancer(
6255
creds = insecure.NewCredentials()
6356
}
6457

58+
bc := &balancer.Config{
59+
PartitionCount: dst.PartitionCount,
60+
ReplicationFactor: dst.ReplicationFactor,
61+
Load: dst.Load,
62+
PickerWidth: dst.PickerWidth,
63+
}
64+
65+
bcjson, err := bc.ServiceConfigJSON()
66+
if err != nil {
67+
return nil, err
68+
}
69+
6570
// Append common options
6671
options = append(
6772
options,
68-
grpc.WithDefaultServiceConfig(grpcServicePolicy),
73+
grpc.WithDefaultServiceConfig(bcjson),
6974
grpc.WithTransportCredentials(creds),
7075
)
7176

@@ -82,7 +87,7 @@ func NewCheckEngineWithBalancer(
8287
}
8388
}
8489

85-
conn, err := grpc.Dial(dst.Address, options...)
90+
conn, err := grpc.NewClient(dst.Address, options...)
8691
if err != nil {
8792
return nil, err
8893
}
@@ -112,29 +117,12 @@ func (c *Balancer) Check(ctx context.Context, request *base.PermissionCheckReque
112117

113118
isRelational := engines.IsRelational(en, request.GetPermission())
114119

115-
// Create a new xxhash instance.
116-
h := xxhash.New()
117-
118-
// Generate a unique key for the request based on its relational state.
119-
// This key helps in distributing the request.
120-
_, err = h.Write([]byte(engines.GenerateKey(request, isRelational)))
121-
if err != nil {
122-
slog.ErrorContext(ctx, err.Error())
123-
return &base.PermissionCheckResponse{
124-
Can: base.CheckResult_CHECK_RESULT_DENIED,
125-
Metadata: &base.PermissionCheckResponseMetadata{
126-
CheckCount: 0,
127-
},
128-
}, err
129-
}
130-
k := hex.EncodeToString(h.Sum(nil))
131-
132120
// Add a timeout of 2 seconds to the context and also set the generated key as a value.
133-
withTimeout, cancel := context.WithTimeout(context.WithValue(ctx, balancer.Key, k), 4*time.Second)
121+
withTimeout, cancel := context.WithTimeout(context.WithValue(ctx, balancer.Key, []byte(engines.GenerateKey(request, isRelational))), 4*time.Second)
134122
defer cancel()
135123

136124
// Logging the intention to forward the request to the underlying client.
137-
slog.DebugContext(ctx, "Forwarding request with key to the underlying client", slog.String("key", k))
125+
slog.InfoContext(ctx, "Forwarding request with key to the underlying client")
138126

139127
// Perform the actual permission check by making a call to the underlying client.
140128
response, err := c.client.Check(withTimeout, request)

internal/info.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var Identifier = ""
2323
*/
2424
const (
2525
// Version is the last release of the Permify (e.g. v0.1.0)
26-
Version = "v1.2.7"
26+
Version = "v1.2.8"
2727
)
2828

2929
// Function to create a single line of the ASCII art with centered content and color

0 commit comments

Comments
 (0)