コード例 #1
0
 public SymCacheController(SymCacheRepository repository,
                           IBackgroundTranscodeQueue transcodeQueue,
                           SymCacheTranscoder transcoder,
                           IOptions <SymCacheOptions> options)
 {
     this.repository     = repository;
     this.transcodeQueue = transcodeQueue;
     this.transcoder     = transcoder;
     transcoderVersion   = options.Value.TranscoderVersion;
 }
コード例 #2
0
        public BackgroundTranscodeService(SymCacheRepository repository, SymCacheTranscoder transcoder)
        {
            Debug.Assert(repository != null);
            Debug.Assert(transcoder != null);

            this.repository = repository;
            this.transcoder = transcoder;

            // Use one background transcode thread for each processor.
            threads = new Thread[Environment.ProcessorCount];
        }
コード例 #3
0
    public SymCacheTranscoder(SymbolServerClient symbolServer, SymCacheRepository repository,
                              IOptions <SymCacheOptions> options)
    {
        this.symbolServer = symbolServer;
        this.repository   = repository;
        transcoderVersion = options.Value.TranscoderVersion;
        transcoderPath    = options.Value.TranscoderPath;

        // Use a separate child directory for transcoding file temporarily to avoid file corruption in case of
        // concurrency. But put this temporary directory under the same parent as the final result directory, so that
        // the final, renamed file still ends up with appropriate permissions (renames on NTFS leave permissions as-is).
        tempDirectory = Path.Combine(Path.GetFullPath(options.Value.SymCacheDirectory), ".temp");
    }
コード例 #4
0
    public async Task <string> TryTranscodeAsync(SymCacheKey key, CancellationToken cancellationToken)
    {
        // Check whether a result already exists. If so, don't try to transcode again.
        CacheResult result = repository.Find(key);

        if (result.Status == CacheStatus.NegativelyCached)
        {
            return(null);
        }
        else if (result.Status == CacheStatus.PositivelyCached)
        {
            return(result.Path);
        }

        Debug.Assert(result.Status == CacheStatus.NotCached);

        string pdbPath = await symbolServer.TryGetPdbPathAsync(key.PdbName, key.PdbId, key.PdbAge, cancellationToken);

        if (pdbPath == null)
        {
            repository.MarkNegativelyCached(key);
            return(null);
        }

        // Use a separate, random directory under the temp directory so that concurrent transcodes do not collide.
        using (TempDirectory randomDirectory = new TempDirectory(Path.Combine(tempDirectory,
                                                                              Guid.NewGuid().ToString())))
        {
            string pdbDirectory = Path.Combine(randomDirectory.FullName, "pdb");

            Directory.CreateDirectory(pdbDirectory);

            // Cache the PDB from the sybol server locally, so transcoding (which is expensive) is accessing a local
            // file.
            string localPdbPath = Path.Combine(pdbDirectory, Path.GetFileName(pdbPath));

            try
            {
                File.Copy(pdbPath, localPdbPath);
            }
            catch
            {
                // The symbol server may report a PDB path that does not exist or is not accessible.
                repository.MarkNegativelyCached(key);
                return(null);
            }

            string expectedOutputPath = Path.Combine(randomDirectory.FullName, SymCacheRepository.GetRelativePath(key));
            await RunTranscoderAsync(localPdbPath, randomDirectory.FullName, cancellationToken);

            if (!File.Exists(expectedOutputPath))
            {
                // Transcoding failed for some reason.
                repository.MarkNegativelyCached(key);
                return(null);
            }

            string finalOutputPath = repository.GetPath(key);
            Directory.CreateDirectory(Path.GetDirectoryName(finalOutputPath));

            try
            {
                File.Move(expectedOutputPath, finalOutputPath);
            }
            catch
            {
                // In case of concurrency, the file may already exist. If so, the transcode is done.
                if (!File.Exists(finalOutputPath))
                {
                    // But if not, the transcode failed.
                    repository.MarkNegativelyCached(key);
                    return(null);
                }
            }

            return(finalOutputPath);
        }
    }