private bool TryAcquireLockWithRetries(ITracer tracer, FileBasedLock mappingLock) { const int NumRetries = 100; const int WaitTimeMs = 100; for (int i = 0; i < NumRetries; ++i) { if (mappingLock.TryAcquireLock()) { return(true); } else if (i < NumRetries - 1) { Thread.Sleep(WaitTimeMs); if (i % 20 == 0) { tracer.RelatedInfo("Waiting to acquire local cacke metadata lock file"); } } } return(false); }
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); } }