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:
commit
0d470ecea0
5 changed files with 73 additions and 9 deletions
|
@ -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)
|
||||||
|
|
|
@ -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}'");
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue