public bool TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers( ITracer tracer, GVFSConfig gvfsConfig, CacheServerInfo currentCacheServer, string localCacheRoot, out string localCacheKey, out string errorMessage) { if (gvfsConfig == null) { throw new ArgumentNullException(nameof(gvfsConfig)); } 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 = new FileBasedLock( this.fileSystem, tracer, lockPath, this.enlistment.EnlistmentRoot, overwriteExistingLock: true)) { 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, gvfsConfig, 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); } }
private bool TryGetLocalCacheKeyFromRemoteCacheServers( ITracer tracer, GVFSConfig gvfsConfig, CacheServerInfo currentCacheServer, FileBasedDictionary <string, string> mappingFile, out string localCacheKey, out string error) { error = null; localCacheKey = null; try { if (this.TryFindExistingLocalCacheKey(mappingFile, gvfsConfig.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 gvfsConfig.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); }