Esempio n. 1
0
        protected override void Execute(GVFSEnlistment enlistment)
        {
            using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "Prefetch"))
            {
                if (this.Verbose)
                {
                    tracer.AddDiagnosticConsoleEventListener(EventLevel.Informational, Keywords.Any);
                }
                else
                {
                    tracer.AddPrettyConsoleEventListener(EventLevel.Error, Keywords.Any);
                }

                tracer.AddLogFileEventListener(
                    GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Prefetch),
                    EventLevel.Informational,
                    Keywords.Any);
                tracer.WriteStartEvent(
                    enlistment.EnlistmentRoot,
                    enlistment.RepoUrl,
                    enlistment.CacheServerUrl);

                try
                {
                    EventMetadata metadata = new EventMetadata();
                    metadata.Add("Commits", this.Commits);
                    metadata.Add("PathWhitelist", this.PathWhitelist);
                    metadata.Add("PathWhitelistFile", this.PathWhitelistFile);
                    tracer.RelatedEvent(EventLevel.Informational, "PerformPrefetch", metadata);

                    if (this.Commits)
                    {
                        if (!string.IsNullOrEmpty(this.PathWhitelistFile) ||
                            !string.IsNullOrWhiteSpace(this.PathWhitelist))
                        {
                            this.ReportErrorAndExit("Cannot supply both --commits (-c) and --folders (-f)");
                        }

                        PrefetchHelper prefetchHelper = new PrefetchHelper(
                            tracer,
                            enlistment,
                            DownloadThreadCount);

                        if (this.Verbose)
                        {
                            prefetchHelper.TryPrefetchCommitsAndTrees();
                        }
                        else
                        {
                            this.ShowStatusWhileRunning(
                                () => { return(prefetchHelper.TryPrefetchCommitsAndTrees()); },
                                "Fetching commits and trees");
                        }

                        return;
                    }

                    FetchHelper fetchHelper = new FetchHelper(
                        tracer,
                        enlistment,
                        ChunkSize,
                        SearchThreadCount,
                        DownloadThreadCount,
                        IndexThreadCount);

                    if (!FetchHelper.TryLoadPathWhitelist(tracer, this.PathWhitelist, this.PathWhitelistFile, enlistment, fetchHelper.PathWhitelist))
                    {
                        Environment.ExitCode = (int)ReturnCode.GenericError;
                        return;
                    }

                    GitProcess        gitProcess = new GitProcess(enlistment);
                    GitProcess.Result result     = gitProcess.RevParse(GVFSConstants.HeadCommitName);
                    if (result.HasErrors)
                    {
                        tracer.RelatedError(result.Errors);
                        this.Output.WriteLine(result.Errors);
                        Environment.ExitCode = (int)ReturnCode.GenericError;
                        return;
                    }

                    string      headCommitId = result.Output;
                    Func <bool> doPrefetch   =
                        () =>
                    {
                        try
                        {
                            fetchHelper.FastFetch(headCommitId.Trim(), isBranch: false);
                            return(!fetchHelper.HasFailures);
                        }
                        catch (FetchHelper.FetchException e)
                        {
                            tracer.RelatedError(e.Message);
                            return(false);
                        }
                    };

                    if (this.Verbose)
                    {
                        doPrefetch();
                    }
                    else
                    {
                        this.ShowStatusWhileRunning(doPrefetch, "Fetching blobs");
                    }

                    if (fetchHelper.HasFailures)
                    {
                        Environment.ExitCode = 1;
                    }
                }
                catch (AggregateException aggregateException)
                {
                    this.Output.WriteLine("Cannot prefetch @ {0}:", enlistment.EnlistmentRoot);
                    foreach (Exception innerException in aggregateException.Flatten().InnerExceptions)
                    {
                        tracer.RelatedError(
                            new EventMetadata
                        {
                            { "Verb", typeof(PrefetchVerb).Name },
                            { "ErrorMessage", $"Unhandled {innerException.GetType().Name}: {innerException.Message}" },
                            { "Exception", innerException.ToString() }
                        });
                    }

                    Environment.ExitCode = (int)ReturnCode.GenericError;
                }
                catch (VerbAbortedException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    this.Output.WriteLine("Cannot prefetch @ {0}:", enlistment.EnlistmentRoot);
                    tracer.RelatedError(
                        new EventMetadata
                    {
                        { "Verb", typeof(PrefetchVerb).Name },
                        { "ErrorMessage", $"Unhandled {e.GetType().Name}: {e.Message}" },
                        { "Exception", e.ToString() }
                    });
                }
            }
        }
Esempio n. 2
0
        private void PrefetchBlobs(ITracer tracer, GVFSEnlistment enlistment, GitObjectsHttpRequestor blobRequestor, CacheServerInfo cacheServer)
        {
            PrefetchHelper fetchHelper = new PrefetchHelper(
                tracer,
                enlistment,
                blobRequestor,
                ChunkSize,
                SearchThreadCount,
                DownloadThreadCount,
                IndexThreadCount);

            string error;

            if (!PrefetchHelper.TryLoadFolderList(enlistment, this.Folders, this.FoldersListFile, fetchHelper.FolderList, out error))
            {
                this.ReportErrorAndExit(tracer, error);
            }

            if (!PrefetchHelper.TryLoadFileList(enlistment, this.Files, fetchHelper.FileList, out error))
            {
                this.ReportErrorAndExit(tracer, error);
            }

            if (fetchHelper.FolderList.Count == 0 &&
                fetchHelper.FileList.Count == 0)
            {
                this.ReportErrorAndExit(tracer, "Did you mean to fetch all blobs? If so, specify `--files *` to confirm.");
            }

            if (this.HydrateFiles)
            {
                if (!this.CheckIsMounted(verbose: true))
                {
                    this.ReportErrorAndExit("You can only specify --hydrate if the repo is mounted. Run 'gvfs mount' and try again.");
                }
            }

            GitProcess gitProcess = new GitProcess(enlistment);

            GitProcess.Result result = gitProcess.RevParse(GVFSConstants.DotGit.HeadName);
            if (result.HasErrors)
            {
                tracer.RelatedError(result.Errors);
                this.Output.WriteLine(result.Errors);
                Environment.ExitCode = (int)ReturnCode.GenericError;
                return;
            }

            int matchedBlobCount    = 0;
            int downloadedBlobCount = 0;
            int readFileCount       = 0;

            string      headCommitId = result.Output;
            Func <bool> doPrefetch   =
                () =>
            {
                try
                {
                    fetchHelper.PrefetchWithStats(
                        headCommitId.Trim(),
                        isBranch: false,
                        readFilesAfterDownload: this.HydrateFiles,
                        matchedBlobCount: out matchedBlobCount,
                        downloadedBlobCount: out downloadedBlobCount,
                        readFileCount: out readFileCount);
                    return(!fetchHelper.HasFailures);
                }
                catch (PrefetchHelper.FetchException e)
                {
                    tracer.RelatedError(e.Message);
                    return(false);
                }
            };

            if (this.Verbose)
            {
                doPrefetch();
            }
            else
            {
                string message =
                    this.HydrateFiles
                    ? "Fetching blobs and hydrating files "
                    : "Fetching blobs ";
                this.ShowStatusWhileRunning(doPrefetch, message + this.GetCacheServerDisplay(cacheServer));
            }

            if (fetchHelper.HasFailures)
            {
                Environment.ExitCode = 1;
            }
            else
            {
                Console.WriteLine();
                Console.WriteLine("Stats:");
                Console.WriteLine("  Matched blobs:    " + matchedBlobCount);
                Console.WriteLine("  Already cached:   " + (matchedBlobCount - downloadedBlobCount));
                Console.WriteLine("  Downloaded:       " + downloadedBlobCount);
                if (this.HydrateFiles)
                {
                    Console.WriteLine("  Hydrated files:   " + readFileCount);
                }
            }
        }
Esempio n. 3
0
        private void PerformPrefetch(GVFSEnlistment enlistment, ITracer tracer)
        {
            try
            {
                EventMetadata metadata = new EventMetadata();
                metadata.Add("Commits", this.Commits);
                metadata.Add("PathWhitelist", this.PathWhitelist);
                metadata.Add("PathWhitelistFile", this.PathWhitelistFile);
                tracer.RelatedEvent(EventLevel.Informational, "PerformPrefetch", metadata);

                if (this.Commits)
                {
                    if (!string.IsNullOrEmpty(this.PathWhitelistFile) ||
                        !string.IsNullOrWhiteSpace(this.PathWhitelist))
                    {
                        this.ReportErrorAndExit("Cannot supply both --commits (-c) and --folders (-f)");
                    }

                    PrefetchHelper prefetchHelper = new PrefetchHelper(
                        tracer,
                        enlistment,
                        DownloadThreadCount);
                    prefetchHelper.PrefetchCommitsAndTrees();
                    return;
                }

                FetchHelper fetchHelper = new FetchHelper(
                    tracer,
                    enlistment,
                    ChunkSize,
                    SearchThreadCount,
                    DownloadThreadCount,
                    IndexThreadCount);

                if (!FetchHelper.TryLoadPathWhitelist(this.PathWhitelist, this.PathWhitelistFile, tracer, fetchHelper.PathWhitelist))
                {
                    Environment.ExitCode = (int)ReturnCode.GenericError;
                    return;
                }

                bool   gvfsHeadFileExists;
                string error;
                string projectedCommitId;

                if (!enlistment.TryParseGVFSHeadFile(out gvfsHeadFileExists, out error, out projectedCommitId))
                {
                    tracer.RelatedError(error);
                    this.Output.WriteLine(error);
                    Environment.ExitCode = (int)ReturnCode.GenericError;
                    return;
                }

                fetchHelper.FastFetch(projectedCommitId.Trim(), isBranch: false);
                if (fetchHelper.HasFailures)
                {
                    Environment.ExitCode = 1;
                }
            }
            catch (AggregateException e)
            {
                this.Output.WriteLine("Cannot prefetch @ {0}:", enlistment.EnlistmentRoot);
                foreach (Exception ex in e.Flatten().InnerExceptions)
                {
                    this.Output.WriteLine("Exception: {0}", ex.ToString());
                }

                Environment.ExitCode = (int)ReturnCode.GenericError;
            }
            catch (VerbAbortedException)
            {
                throw;
            }
            catch (Exception e)
            {
                this.ReportErrorAndExit("Cannot prefetch @ {0}: {1}", enlistment.EnlistmentRoot, e.ToString());
            }
        }