Merge branch 'zachmu/remote-ref-replication' of github.com:dolthub/dolt into zachmu/remote-ref-replication

This commit is contained in:
Zach Musgrave
2023-02-08 17:45:11 -08:00
@@ -216,9 +216,9 @@ func (rrd ReadReplicaDatabase) PullFromRemote(ctx *sql.Context) error {
return nil
}
// CreateLocalBranchFromRemote pulls the given branch from the remote database and creates a local tracking branch for
// it. This is only used for initializing a new local branch being pulled from a remote during connection
// initialization, and doesn't do the full work of remote synchronization that happens on transaction start.
// CreateLocalBranchFromRemote pulls the given branch from the remote database and creates a local tracking branch for
// it. This is only used for initializing a new local branch being pulled from a remote during connection
// initialization, and doesn't do the full work of remote synchronization that happens on transaction start.
func (rrd ReadReplicaDatabase) CreateLocalBranchFromRemote(ctx *sql.Context, branchRef ref.BranchRef) error {
_, err := rrd.limiter.Run(ctx, "pullNewBranch", func() (any, error) {
// because several clients can queue up waiting to create the same local branch, double check to see if this
@@ -272,7 +272,7 @@ type pullBehavior bool
const pullBehavior_fastForward pullBehavior = false
const pullBehavior_forcePull pullBehavior = true
// pullBranchesAndUpdateWorkingSet pulls the remote branches named. If a corresponding local branch exists, it will be
// pullBranchesAndUpdateWorkingSet pulls the remote branches named. If a corresponding local branch exists, it will be
// fast-forwarded. If it doesn't exist, it will be created. Afterward, the working set of the current branch is
// updated if the current branch ref was updated by the pull.
func pullBranchesAndUpdateWorkingSet(
@@ -283,7 +283,7 @@ func pullBranchesAndUpdateWorkingSet(
currentBranchRef ref.DoltRef,
behavior pullBehavior,
) error {
remoteRefsByPath, err := pullBranches(ctx, rrd, remoteRefs, localRefs, behavior)
if err != nil {
return err
@@ -352,11 +352,11 @@ func pullBranchesAndUpdateWorkingSet(
// pullBranches pulls the remote branches named and returns the map of their hashes keyed by branch path.
func pullBranches(
ctx *sql.Context,
rrd ReadReplicaDatabase,
remoteRefs []doltdb.RefWithHash,
localRefs []doltdb.RefWithHash,
behavior pullBehavior,
ctx *sql.Context,
rrd ReadReplicaDatabase,
remoteRefs []doltdb.RefWithHash,
localRefs []doltdb.RefWithHash,
behavior pullBehavior,
) (map[string]doltdb.RefWithHash, error) {
localRefsByPath := make(map[string]doltdb.RefWithHash)
remoteRefsByPath := make(map[string]doltdb.RefWithHash)
@@ -380,17 +380,17 @@ func pullBranches(
_, err := rrd.limiter.Run(ctx, "-all", func() (any, error) {
pullErr := rrd.ddb.PullChunks(ctx, rrd.tmpDir, rrd.srcDB, remoteHashes, nil)
REFS: // every successful pass through the loop below must end with CONTINUE REFS to get out of the retry loop
REFS: // every successful pass through the loop below must end with CONTINUE REFS to get out of the retry loop
for _, remoteRef := range remoteRefs {
trackingRef := ref.NewRemoteRef(rrd.remote.Name, remoteRef.Ref.GetPath())
localRef, localRefExists := localRefsByPath[remoteRef.Ref.GetPath()]
// loop on optimistic lock failures
OPTIMISTIC_RETRY:
OPTIMISTIC_RETRY:
for {
if pullErr != nil || localRefExists {
pullErr = nil
// TODO: this should work for workspaces too but doesn't, only branches
if localRef.Ref.GetType() == ref.BranchRefType {
err := rrd.pullLocalBranch(ctx, localRef, remoteRef, trackingRef, behavior)
@@ -400,7 +400,7 @@ OPTIMISTIC_RETRY:
return nil, err
}
}
continue REFS
} else {
switch remoteRef.Ref.GetType() {
@@ -421,7 +421,7 @@ OPTIMISTIC_RETRY:
} else if err != nil {
return nil, err
}
continue REFS
default:
ctx.GetLogger().Warnf("skipping replication for unhandled remote ref %s", remoteRef.Ref.String())
@@ -442,8 +442,8 @@ OPTIMISTIC_RETRY:
func (rrd ReadReplicaDatabase) createNewBranchFromRemote(ctx *sql.Context, remoteRef doltdb.RefWithHash, trackingRef ref.RemoteRef) error {
ctx.GetLogger().Tracef("creating local branch %s", remoteRef.Ref.GetPath())
// If a local branch isn't present for the remote branch, create a new branch for it. We need to use
// NewBranchAtCommit so that the branch has its associated working set created at the same time. Creating
// If a local branch isn't present for the remote branch, create a new branch for it. We need to use
// NewBranchAtCommit so that the branch has its associated working set created at the same time. Creating
// branch refs without associate working sets causes errors in other places.
spec, err := doltdb.NewCommitSpec(remoteRef.Hash.String())
if err != nil {
@@ -465,24 +465,24 @@ func (rrd ReadReplicaDatabase) createNewBranchFromRemote(ctx *sql.Context, remot
}
func (rrd ReadReplicaDatabase) pullLocalBranch(ctx *sql.Context, localRef doltdb.RefWithHash, remoteRef doltdb.RefWithHash, trackingRef ref.RemoteRef, behavior pullBehavior) error {
if localRef.Hash != remoteRef.Hash {
if behavior == pullBehavior_forcePull {
err := rrd.ddb.SetHead(ctx, remoteRef.Ref, remoteRef.Hash)
if err != nil {
return err
}
} else {
err := rrd.ddb.FastForwardToHash(ctx, remoteRef.Ref, remoteRef.Hash)
if err != nil {
return err
}
if localRef.Hash != remoteRef.Hash {
if behavior == pullBehavior_forcePull {
err := rrd.ddb.SetHead(ctx, remoteRef.Ref, remoteRef.Hash)
if err != nil {
return err
}
err := rrd.ddb.SetHead(ctx, trackingRef, remoteRef.Hash)
} else {
err := rrd.ddb.FastForwardToHash(ctx, remoteRef.Ref, remoteRef.Hash)
if err != nil {
return err
}
}
err := rrd.ddb.SetHead(ctx, trackingRef, remoteRef.Hash)
if err != nil {
return err
}
}
return nil
}