예제 #1
0
        public bool TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers(
            ITracer tracer,
            ServerGSDConfig serverGSDConfig,
            CacheServerInfo currentCacheServer,
            string localCacheRoot,
            out string localCacheKey,
            out string errorMessage)
        {
            if (serverGSDConfig == null)
            {
                throw new ArgumentNullException(nameof(serverGSDConfig));
            }

            localCacheKey = null;
            errorMessage  = string.Empty;

            try
            {
                // A lock is required because FileBasedDictionary is not multi-process safe, neither is the act of adding a new cache
                string lockPath = Path.Combine(localCacheRoot, MappingFile + ".lock");
                this.fileSystem.CreateDirectory(localCacheRoot);

                using (FileBasedLock mappingLock = GSDPlatform.Instance.CreateFileBasedLock(
                           this.fileSystem,
                           tracer,
                           lockPath))
                {
                    if (!this.TryAcquireLockWithRetries(tracer, mappingLock))
                    {
                        errorMessage = "Failed to acquire lock file at " + lockPath;
                        tracer.RelatedError(nameof(this.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers) + ": " + errorMessage);
                        return(false);
                    }

                    FileBasedDictionary <string, string> mappingFile;
                    if (this.TryOpenMappingFile(tracer, localCacheRoot, out mappingFile, out errorMessage))
                    {
                        try
                        {
                            string mappingDataVersion;
                            if (mappingFile.TryGetValue(MappingVersionKey, out mappingDataVersion))
                            {
                                if (mappingDataVersion != CurrentMappingDataVersion)
                                {
                                    errorMessage = string.Format("Mapping file has different version than expected: {0} Actual: {1}", CurrentMappingDataVersion, mappingDataVersion);
                                    tracer.RelatedError(nameof(this.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers) + ": " + errorMessage);
                                    return(false);
                                }
                            }
                            else
                            {
                                mappingFile.SetValueAndFlush(MappingVersionKey, CurrentMappingDataVersion);
                            }

                            if (mappingFile.TryGetValue(this.ToMappingKey(this.enlistment.RepoUrl), out localCacheKey) ||
                                (currentCacheServer.HasValidUrl() && mappingFile.TryGetValue(this.ToMappingKey(currentCacheServer.Url), out localCacheKey)))
                            {
                                EventMetadata metadata = CreateEventMetadata();
                                metadata.Add("localCacheKey", localCacheKey);
                                metadata.Add("this.enlistment.RepoUrl", this.enlistment.RepoUrl);
                                metadata.Add("currentCacheServer", currentCacheServer.ToString());
                                metadata.Add(TracingConstants.MessageKey.InfoMessage, nameof(this.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers) + ": Found existing local cache key");
                                tracer.RelatedEvent(EventLevel.Informational, "LocalCacheResolver_ExistingKey", metadata);

                                return(true);
                            }
                            else
                            {
                                EventMetadata metadata = CreateEventMetadata();
                                metadata.Add("this.enlistment.RepoUrl", this.enlistment.RepoUrl);
                                metadata.Add("currentCacheServer", currentCacheServer.ToString());

                                string getLocalCacheKeyError;
                                if (this.TryGetLocalCacheKeyFromRemoteCacheServers(tracer, serverGSDConfig, currentCacheServer, mappingFile, out localCacheKey, out getLocalCacheKeyError))
                                {
                                    metadata.Add("localCacheKey", localCacheKey);
                                    metadata.Add(TracingConstants.MessageKey.InfoMessage, nameof(this.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers) + ": Generated new local cache key");
                                    tracer.RelatedEvent(EventLevel.Informational, "LocalCacheResolver_NewKey", metadata);
                                    return(true);
                                }

                                metadata.Add("getLocalCacheKeyError", getLocalCacheKeyError);
                                tracer.RelatedError(metadata, nameof(this.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers) + ": TryGetLocalCacheKeyFromRemoteCacheServers failed");

                                errorMessage = "Failed to generate local cache key";
                                return(false);
                            }
                        }
                        finally
                        {
                            mappingFile.Dispose();
                        }
                    }

                    return(false);
                }
            }
            catch (Exception e)
            {
                EventMetadata metadata = CreateEventMetadata(e);
                metadata.Add("this.enlistment.RepoUrl", this.enlistment.RepoUrl);
                metadata.Add("currentCacheServer", currentCacheServer.ToString());
                tracer.RelatedError(metadata, nameof(this.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers) + ": Caught exception");

                errorMessage = string.Format("Exception while getting local cache key: {0}", e.Message);
                return(false);
            }
        }
예제 #2
0
        private bool TryGetLocalCacheKeyFromRemoteCacheServers(
            ITracer tracer,
            ServerGSDConfig serverGSDConfig,
            CacheServerInfo currentCacheServer,
            FileBasedDictionary <string, string> mappingFile,
            out string localCacheKey,
            out string error)
        {
            error         = null;
            localCacheKey = null;

            try
            {
                if (this.TryFindExistingLocalCacheKey(mappingFile, serverGSDConfig.CacheServers, out localCacheKey))
                {
                    EventMetadata metadata = CreateEventMetadata();
                    metadata.Add("currentCacheServer", currentCacheServer.ToString());
                    metadata.Add("localCacheKey", localCacheKey);
                    metadata.Add("this.enlistment.RepoUrl", this.enlistment.RepoUrl);
                    metadata.Add(TracingConstants.MessageKey.InfoMessage, nameof(this.TryGetLocalCacheKeyFromRemoteCacheServers) + ": Found an existing a local key by cross referencing");
                    tracer.RelatedEvent(EventLevel.Informational, "LocalCacheResolver_ExistingKeyFromCrossReferencing", metadata);
                }
                else
                {
                    localCacheKey = Guid.NewGuid().ToString("N");

                    EventMetadata metadata = CreateEventMetadata();
                    metadata.Add("currentCacheServer", currentCacheServer.ToString());
                    metadata.Add("localCacheKey", localCacheKey);
                    metadata.Add("this.enlistment.RepoUrl", this.enlistment.RepoUrl);
                    metadata.Add(TracingConstants.MessageKey.InfoMessage, nameof(this.TryGetLocalCacheKeyFromRemoteCacheServers) + ": Generated a new local key after cross referencing");
                    tracer.RelatedEvent(EventLevel.Informational, "LocalCacheResolver_NewKeyAfterCrossReferencing", metadata);
                }

                List <KeyValuePair <string, string> > mappingFileUpdates = new List <KeyValuePair <string, string> >();

                mappingFileUpdates.Add(new KeyValuePair <string, string>(this.ToMappingKey(this.enlistment.RepoUrl), localCacheKey));

                if (currentCacheServer.HasValidUrl())
                {
                    mappingFileUpdates.Add(new KeyValuePair <string, string>(this.ToMappingKey(currentCacheServer.Url), localCacheKey));
                }

                foreach (CacheServerInfo cacheServer in serverGSDConfig.CacheServers)
                {
                    string persistedLocalCacheKey;
                    if (mappingFile.TryGetValue(this.ToMappingKey(cacheServer.Url), out persistedLocalCacheKey))
                    {
                        if (!string.Equals(persistedLocalCacheKey, localCacheKey, StringComparison.OrdinalIgnoreCase))
                        {
                            EventMetadata metadata = CreateEventMetadata();
                            metadata.Add("cacheServer", cacheServer.ToString());
                            metadata.Add("persistedLocalCacheKey", persistedLocalCacheKey);
                            metadata.Add("localCacheKey", localCacheKey);
                            metadata.Add("currentCacheServer", currentCacheServer.ToString());
                            metadata.Add("this.enlistment.RepoUrl", this.enlistment.RepoUrl);
                            tracer.RelatedWarning(metadata, nameof(this.TryGetLocalCacheKeyFromRemoteCacheServers) + ": Overwriting persisted cache key with new value");

                            mappingFileUpdates.Add(new KeyValuePair <string, string>(this.ToMappingKey(cacheServer.Url), localCacheKey));
                        }
                    }
                    else
                    {
                        mappingFileUpdates.Add(new KeyValuePair <string, string>(this.ToMappingKey(cacheServer.Url), localCacheKey));
                    }
                }

                mappingFile.SetValuesAndFlush(mappingFileUpdates);
            }
            catch (Exception e)
            {
                EventMetadata metadata = CreateEventMetadata(e);
                tracer.RelatedError(metadata, nameof(this.TryGetLocalCacheKeyFromRemoteCacheServers) + ": Caught exception while getting local key");
                error = string.Format("Exception while getting local cache key: {0}", e.Message);
                return(false);
            }

            return(true);
        }