in GVFS/GVFS.Common/LocalCacheResolver.cs [39:152]
public bool TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers(
ITracer tracer,
ServerGVFSConfig serverGVFSConfig,
CacheServerInfo currentCacheServer,
string localCacheRoot,
out string localCacheKey,
out string errorMessage)
{
if (serverGVFSConfig == null)
{
throw new ArgumentNullException(nameof(serverGVFSConfig));
}
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");
string createDirectoryError;
if (!GVFSPlatform.Instance.FileSystem.TryCreateDirectoryAccessibleByAuthUsers(localCacheRoot, out createDirectoryError, tracer))
{
errorMessage = $"Failed to create '{localCacheRoot}': {createDirectoryError}";
return false;
}
using (FileBasedLock mappingLock = GVFSPlatform.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, serverGVFSConfig, 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;
}
}