Merge pull request #3446 from dotnet/troy-3220

Enable project model server to clear workspace cache forceful after restore completion
This commit is contained in:
Troy Dai 2016-06-15 23:22:44 -07:00 committed by GitHub
commit 0d470ecea0
5 changed files with 73 additions and 9 deletions

View file

@ -53,7 +53,7 @@ namespace Microsoft.DotNet.ProjectModel
.FirstOrDefault(c => Equals(c.TargetFramework, framework) && string.IsNullOrEmpty(c.RuntimeIdentifier)); .FirstOrDefault(c => Equals(c.TargetFramework, framework) && string.IsNullOrEmpty(c.RuntimeIdentifier));
} }
public ProjectContextCollection GetProjectContextCollection(string projectPath) public ProjectContextCollection GetProjectContextCollection(string projectPath, bool clearCache)
{ {
var normalizedPath = ProjectPathHelper.NormalizeProjectDirectoryPath(projectPath); var normalizedPath = ProjectPathHelper.NormalizeProjectDirectoryPath(projectPath);
if (normalizedPath == null) if (normalizedPath == null)
@ -61,12 +61,24 @@ namespace Microsoft.DotNet.ProjectModel
return null; return null;
} }
if (clearCache)
{
_projectContextsCache.Clear();
_projectsCache.Clear();
_lockFileCache.Clear();
}
return _projectContextsCache.AddOrUpdate( return _projectContextsCache.AddOrUpdate(
normalizedPath, normalizedPath,
key => AddProjectContextEntry(key, null), key => AddProjectContextEntry(key, null),
(key, oldEntry) => AddProjectContextEntry(key, oldEntry)); (key, oldEntry) => AddProjectContextEntry(key, oldEntry));
} }
public ProjectContextCollection GetProjectContextCollection(string projectPath)
{
return GetProjectContextCollection(projectPath, clearCache: false);
}
public Project GetProject(string projectDirectory) => GetProjectCore(projectDirectory)?.Model; public Project GetProject(string projectDirectory) => GetProjectCore(projectDirectory)?.Model;
private LockFile GetLockFile(string projectDirectory) private LockFile GetLockFile(string projectDirectory)

View file

@ -19,9 +19,13 @@ namespace Microsoft.DotNet.ProjectModel.Server
public ErrorMessage GlobalErrorMessage { get; set; } public ErrorMessage GlobalErrorMessage { get; set; }
public Dictionary<NuGetFramework, ProjectContextSnapshot> ProjectContexts { get; } = new Dictionary<NuGetFramework, ProjectContextSnapshot>(); public Dictionary<NuGetFramework, ProjectContextSnapshot> ProjectContexts { get; } = new Dictionary<NuGetFramework, ProjectContextSnapshot>();
public static ProjectSnapshot Create(string projectDirectory, string configuration, DesignTimeWorkspace workspaceContext, IReadOnlyList<string> projectSearchPaths) public static ProjectSnapshot Create(string projectDirectory,
string configuration,
DesignTimeWorkspace workspaceContext,
IReadOnlyList<string> projectSearchPaths,
bool clearWorkspaceContextCache)
{ {
var projectContextsCollection = workspaceContext.GetProjectContextCollection(projectDirectory); var projectContextsCollection = workspaceContext.GetProjectContextCollection(projectDirectory, clearWorkspaceContextCache);
if (!projectContextsCollection.ProjectContexts.Any()) if (!projectContextsCollection.ProjectContexts.Any())
{ {
throw new InvalidOperationException($"Unable to find project.json in '{projectDirectory}'"); throw new InvalidOperationException($"Unable to find project.json in '{projectDirectory}'");

View file

@ -25,7 +25,7 @@ namespace Microsoft.DotNet.ProjectModel.Server
// triggers // triggers
private readonly Trigger<string> _appPath = new Trigger<string>(); private readonly Trigger<string> _appPath = new Trigger<string>();
private readonly Trigger<string> _configure = new Trigger<string>(); private readonly Trigger<string> _configure = new Trigger<string>();
private readonly Trigger<int> _refreshDependencies = new Trigger<int>(); private readonly Trigger<bool> _refreshDependencies = new Trigger<bool>();
private readonly Trigger<int> _filesChanged = new Trigger<int>(); private readonly Trigger<int> _filesChanged = new Trigger<int>();
private ProjectSnapshot _local = new ProjectSnapshot(); private ProjectSnapshot _local = new ProjectSnapshot();
@ -200,8 +200,14 @@ namespace Microsoft.DotNet.ProjectModel.Server
_configure.Value = message.Payload.GetValue("Configuration"); _configure.Value = message.Payload.GetValue("Configuration");
break; break;
case MessageTypes.RefreshDependencies: case MessageTypes.RefreshDependencies:
// In the case of RefreshDependencies request, the cache will not be reset in any case. The value
// is set so as to trigger refresh action in later loop.
_refreshDependencies.Value = false;
break;
case MessageTypes.RestoreComplete: case MessageTypes.RestoreComplete:
_refreshDependencies.Value = 0; // In the case of RestoreComplete request, the value of the 'Reset' property in payload will determine
// if the cache should be reset. If the property doesn't exist, cache will be reset.
_refreshDependencies.Value = message.Payload.HasValues ? message.Payload.Value<bool>("Reset") : true;
break; break;
case MessageTypes.FilesChanged: case MessageTypes.FilesChanged:
_filesChanged.Value = 0; _filesChanged.Value = 0;
@ -240,9 +246,15 @@ namespace Microsoft.DotNet.ProjectModel.Server
_appPath.ClearAssigned(); _appPath.ClearAssigned();
_configure.ClearAssigned(); _configure.ClearAssigned();
_filesChanged.ClearAssigned(); _filesChanged.ClearAssigned();
bool resetCache = _refreshDependencies.WasAssigned ? _refreshDependencies.Value : false;
_refreshDependencies.ClearAssigned(); _refreshDependencies.ClearAssigned();
newSnapshot = ProjectSnapshot.Create(_appPath.Value, _configure.Value, _workspaceContext, _remote.ProjectSearchPaths); newSnapshot = ProjectSnapshot.Create(_appPath.Value,
_configure.Value,
_workspaceContext,
_remote.ProjectSearchPaths,
clearWorkspaceContextCache: resetCache);
} }
if (newSnapshot == null) if (newSnapshot == null)

View file

@ -60,6 +60,11 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
} }
public void SendPayload(string projectPath, string messageType) public void SendPayload(string projectPath, string messageType)
{
SendPayload(projectPath, messageType, new { });
}
public void SendPayload(string projectPath, string messageType, object payload)
{ {
int contextId; int contextId;
if (!_projectContexts.TryGetValue(projectPath, out contextId)) if (!_projectContexts.TryGetValue(projectPath, out contextId))
@ -67,7 +72,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
Assert.True(false, $"Unable to resolve context for {projectPath}"); Assert.True(false, $"Unable to resolve context for {projectPath}");
} }
SendPayload(contextId, messageType); SendPayload(contextId, messageType, payload);
} }
public void SendPayload(int contextId, string messageType) public void SendPayload(int contextId, string messageType)

View file

@ -8,7 +8,6 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.DotNet.TestFramework; using Microsoft.DotNet.TestFramework;
using Microsoft.DotNet.Tools.Test.Utilities; using Microsoft.DotNet.Tools.Test.Utilities;
@ -58,6 +57,38 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
} }
} }
[Theory]
[InlineData(MessageTypes.RefreshDependencies, null)]
[InlineData(MessageTypes.RestoreComplete, null)]
[InlineData(MessageTypes.RestoreComplete, true)]
[InlineData(MessageTypes.RestoreComplete, false)]
public void RefreshDependenciesResultsAreConsistent(string messageType, bool? clearCache)
{
var projectPath = Path.Combine(_testAssetsManager.AssetsRoot, "EmptyNetCoreApp");
Assert.True(Directory.Exists(projectPath));
using (var server = new DthTestServer())
using (var client = new DthTestClient(server))
{
client.Initialize(projectPath);
var originalDependencies = client.DrainMessage(7).Single(m => m.MessageType == MessageTypes.Dependencies)
.RetrievePayloadAs<JObject>();
if (clearCache.HasValue)
{
client.SendPayload(projectPath, messageType, new { Reset = clearCache.Value });
}
else
{
client.SendPayload(projectPath, messageType);
}
var refreshedDependencies = client.DrainTillFirst(MessageTypes.Dependencies).Payload.ToString();
Assert.Equal(originalDependencies.ToString(), refreshedDependencies.ToString());
}
}
[Fact] [Fact]
public void DependencyDiagnsoticsAfterDependencies() public void DependencyDiagnsoticsAfterDependencies()
{ {