func (a *internalAPIServer) commitToReplicas(ctx context.Context, commit *pfs.Commit) error { version, err := a.getVersion(ctx) if err != nil { return err } shards, err := a.router.GetMasterShards(version) if err != nil { return err } var loopErr error var wg sync.WaitGroup for shard := range shards { wg.Add(1) shard := shard go func() { defer wg.Done() clientConns, err := a.router.GetReplicaClientConns(shard, version) if err != nil && loopErr == nil { loopErr = err return } var writers []io.Writer for _, clientConn := range clientConns { pushDiffClient, err := pfs.NewReplicaAPIClient(clientConn).PushDiff( ctx, ) if err != nil && loopErr == nil { loopErr = err return } request := pfs.PushDiffRequest{ Commit: commit, Shard: shard, } writers = append(writers, &pushDiffWriter{ client: pushDiffClient, request: &request, }) } if err = a.driver.PullDiff(commit, shard, io.MultiWriter(writers...)); err != nil && loopErr == nil { loopErr = err return } }() } wg.Wait() return loopErr }
func (a *internalAPIServer) AddShard(_shard uint64, version int64) error { if version == shard.InvalidVersion { return nil } ctx := versionToContext(version, context.Background()) clientConn, err := a.router.GetMasterOrReplicaClientConn(_shard, version) if err != nil { return err } repoInfos, err := pfs.NewInternalAPIClient(clientConn).ListRepo(ctx, &pfs.ListRepoRequest{}) if err != nil { return err } for _, repoInfo := range repoInfos.RepoInfo { if err := a.driver.CreateRepo(repoInfo.Repo); err != nil { return err } commitInfos, err := pfs.NewInternalAPIClient(clientConn).ListCommit(ctx, &pfs.ListCommitRequest{Repo: repoInfo.Repo}) if err != nil { return err } for i := range commitInfos.CommitInfo { commit := commitInfos.CommitInfo[len(commitInfos.CommitInfo)-(i+1)].Commit commitInfo, err := a.driver.InspectCommit(commit, map[uint64]bool{_shard: true}) if err != nil { return err } if commitInfo != nil { // we already have the commit so nothing to do continue } pullDiffRequest := &pfs.PullDiffRequest{ Commit: commit, Shard: _shard, } pullDiffClient, err := pfs.NewReplicaAPIClient(clientConn).PullDiff(ctx, pullDiffRequest) if err != nil { return err } diffReader := protostream.NewStreamingBytesReader(pullDiffClient) if err := a.driver.PushDiff(commit, _shard, diffReader); err != nil { return err } } } return nil }