Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Hiltunen <shiltunen@gitlab.com>2021-02-02 21:45:25 +0300
committerSami Hiltunen <shiltunen@gitlab.com>2021-02-08 17:49:58 +0300
commit0c68a6c5ae348178fe01ef1ad96852d9cde39a01 (patch)
tree989d10cadd7e046ed2a8df668d4e50c8297bfae0 /internal/praefect/router_per_repository.go
parent3a6d6b150d7bd4dc2c84c22e6a0efe3630c3b529 (diff)
support default replication factor in PerRepositoryRouter
This commit adds support for selecting host nodes randomly on repository creation in PerRepositoryRouter. New repositories get random secondaries assigned as host nodes until the default replication factor is met. If the virtual storage has no default replication factor configured, every configured node, except the randomly picked primary, is included as secondaries. This is fallback behavior to match Praefect's behavior prior to variable replication factor.
Diffstat (limited to 'internal/praefect/router_per_repository.go')
-rw-r--r--internal/praefect/router_per_repository.go44
1 files changed, 31 insertions, 13 deletions
diff --git a/internal/praefect/router_per_repository.go b/internal/praefect/router_per_repository.go
index 317e0e21a..9159f3c29 100644
--- a/internal/praefect/router_per_repository.go
+++ b/internal/praefect/router_per_repository.go
@@ -58,23 +58,25 @@ type PrimaryGetter interface {
// PerRepositoryRouter implements a router that routes requests respecting per repository primary nodes.
type PerRepositoryRouter struct {
- conns Connections
- ag AssignmentGetter
- pg PrimaryGetter
- rand Random
- hc HealthChecker
- rs datastore.RepositoryStore
+ conns Connections
+ ag AssignmentGetter
+ pg PrimaryGetter
+ rand Random
+ hc HealthChecker
+ rs datastore.RepositoryStore
+ defaultReplicationFactors map[string]int
}
// NewPerRepositoryRouter returns a new PerRepositoryRouter using the passed configuration.
-func NewPerRepositoryRouter(conns Connections, pg PrimaryGetter, hc HealthChecker, rand Random, rs datastore.RepositoryStore, ag AssignmentGetter) *PerRepositoryRouter {
+func NewPerRepositoryRouter(conns Connections, pg PrimaryGetter, hc HealthChecker, rand Random, rs datastore.RepositoryStore, ag AssignmentGetter, defaultReplicationFactors map[string]int) *PerRepositoryRouter {
return &PerRepositoryRouter{
- conns: conns,
- pg: pg,
- rand: rand,
- hc: hc,
- rs: rs,
- ag: ag,
+ conns: conns,
+ pg: pg,
+ rand: rand,
+ hc: hc,
+ rs: rs,
+ ag: ag,
+ defaultReplicationFactors: defaultReplicationFactors,
}
}
@@ -260,6 +262,11 @@ func (r *PerRepositoryRouter) RouteRepositoryCreation(ctx context.Context, virtu
return RepositoryMutatorRoute{}, err
}
+ replicationFactor := r.defaultReplicationFactors[virtualStorage]
+ if replicationFactor == 1 {
+ return RepositoryMutatorRoute{Primary: primary}, nil
+ }
+
// NodeManagerRouter doesn't consider any secondaries as consistent when creating a repository,
// thus the primary is the only participant in the transaction and the secondaries get replicated to.
// PerRepositoryRouter matches that behavior here for consistency.
@@ -272,6 +279,17 @@ func (r *PerRepositoryRouter) RouteRepositoryCreation(ctx context.Context, virtu
replicationTargets = append(replicationTargets, storage)
}
+ // replicationFactor being zero indicates it has not been configured. If so, we fallback to the behavior
+ // of no assignments and replicate everywhere.
+ if replicationFactor > 1 {
+ r.rand.Shuffle(len(replicationTargets), func(i, j int) {
+ replicationTargets[i], replicationTargets[j] = replicationTargets[j], replicationTargets[i]
+ })
+
+ // deduct one as the primary is also hosting the repository
+ replicationTargets = replicationTargets[:replicationFactor-1]
+ }
+
return RepositoryMutatorRoute{
Primary: primary,
ReplicationTargets: replicationTargets,