Example #1
0
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
}
Example #2
0
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
}