Skip to content
Snippets Groups Projects

Handle repository creations, deletions and renames atomically

Merged Sami Hiltunen requested to merge smh-repository-id-rename-repository into master
4 files
+ 26
54
Compare changes
  • Side-by-side
  • Inline
Files
4
  • Now that Praefect is handling RenameRepository calls without proxying
    them, the logic related to proxying RenameRepository calls can be
    removed. The RPC method is marked as intercepted so the annotations
    can be dropped. As there may still be rename type replication jobs
    in-flight, the replication job handling is still left in place.
@@ -89,7 +89,6 @@ var transactionRPCs = map[string]transactionsCondition{
"/gitaly.ObjectPoolService/DisconnectGitAlternates": transactionsDisabled,
"/gitaly.ObjectPoolService/LinkRepositoryToObjectPool": transactionsDisabled,
"/gitaly.ObjectPoolService/ReduplicateRepository": transactionsDisabled,
"/gitaly.RepositoryService/RenameRepository": transactionsDisabled,
// The following list of RPCs are considered idempotent RPCs: while they write into the
// target repository, this shouldn't ever have any user-visible impact given that they're
@@ -172,12 +171,6 @@ func getReplicationDetails(methodName string, m proto.Message) (datastore.Change
"/gitaly.RepositoryService/CreateRepositoryFromURL",
"/gitaly.RepositoryService/ReplicateRepository":
return datastore.CreateRepo, nil, nil
case "/gitaly.RepositoryService/RenameRepository":
req, ok := m.(*gitalypb.RenameRepositoryRequest)
if !ok {
return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m)
}
return datastore.RenameRepo, datastore.Params{"RelativePath": req.RelativePath}, nil
case "/gitaly.RepositoryService/GarbageCollect":
req, ok := m.(*gitalypb.GarbageCollectRequest)
if !ok {
@@ -1037,17 +1030,6 @@ func (c *Coordinator) newRequestFinalizer(
if err := c.rs.IncrementGeneration(ctx, repositoryID, primary, updatedSecondaries); err != nil {
return fmt.Errorf("increment generation: %w", err)
}
case datastore.RenameRepo:
// Renaming a repository is not idempotent on Gitaly's side. This combined with a failure here results in a problematic state,
// where the client receives an error but can't retry the call as the repository has already been moved on the primary.
// Ideally the rename RPC should copy the repository instead of moving so the client can retry if this failed.
if err := c.rs.RenameRepository(ctx, virtualStorage, targetRepo.GetRelativePath(), primary, params["RelativePath"].(string)); err != nil {
if !errors.Is(err, datastore.RepositoryNotExistsError{}) {
return fmt.Errorf("rename repository: %w", err)
}
ctxlogrus.Extract(ctx).WithError(err).Info("renamed repository does not have a store entry")
}
case datastore.CreateRepo:
repositorySpecificPrimariesEnabled := c.conf.Failover.ElectionStrategy == config.ElectionStrategyPerRepository
variableReplicationFactorEnabled := repositorySpecificPrimariesEnabled &&
Loading