private static IWorkspaceService GetVisualStudioProjectCache(HostWorkspaceServices workspaceServices) { var projectCacheService = new ProjectCacheService(workspaceServices.Workspace, ImplicitCacheTimeoutInMS); var documentTrackingService = workspaceServices.GetService<IDocumentTrackingService>(); // Subscribe to events so that we can cache items from the active document's project var manager = new ActiveProjectCacheManager(documentTrackingService, projectCacheService); // Subscribe to requests to clear the cache var workspaceCacheService = workspaceServices.GetService<IWorkspaceCacheService>(); if (workspaceCacheService != null) { workspaceCacheService.CacheFlushRequested += (s, e) => manager.Clear(); } // Also clear the cache when the solution is cleared or removed. workspaceServices.Workspace.WorkspaceChanged += (s, e) => { if (e.Kind == WorkspaceChangeKind.SolutionCleared || e.Kind == WorkspaceChangeKind.SolutionRemoved) { manager.Clear(); } }; return projectCacheService; }
public void TestEjectFromImplicitCache() { List <Compilation> compilations = new List <Compilation>(); for (int i = 0; i < ProjectCacheService.ImplicitCacheSize + 1; i++) { compilations.Add(CSharpCompilation.Create(i.ToString())); } var weakFirst = ObjectReference.Create(compilations[0]); var weakLast = ObjectReference.Create(compilations[compilations.Count - 1]); var workspace = new AdhocWorkspace(MockHostServices.Instance, workspaceKind: WorkspaceKind.Host); var cache = new ProjectCacheService(workspace, int.MaxValue); for (int i = 0; i < ProjectCacheService.ImplicitCacheSize + 1; i++) { cache.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, compilations[i]); } compilations = null; weakFirst.AssertReleased(); weakLast.AssertHeld(); GC.KeepAlive(cache); }
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { // we support active document tracking only for visual studio workspace host. if (workspaceServices.Workspace is MonoDevelopWorkspace) { // We will finish setting this up in VisualStudioWorkspaceImpl.DeferredInitializationState var projectCacheService = new ProjectCacheService(workspaceServices.Workspace, ImplicitCacheTimeoutInMS); var documentTrackingService = workspaceServices.GetService <IDocumentTrackingService> (); // Subscribe to events so that we can cache items from the active document's project var manager = new ActiveProjectCacheManager(documentTrackingService, projectCacheService); // Subscribe to requests to clear the cache var workspaceCacheService = workspaceServices.GetService <IWorkspaceCacheService> (); if (workspaceCacheService != null) { workspaceCacheService.CacheFlushRequested += (s, e) => manager.Clear(); } // Also clear the cache when the solution is cleared or removed. workspaceServices.Workspace.WorkspaceChanged += (s, e) => { if (e.Kind == WorkspaceChangeKind.SolutionCleared || e.Kind == WorkspaceChangeKind.SolutionRemoved) { manager.Clear(); } }; } // TODO: Handle miscellaneous files workspace later on. return(new ProjectCacheService(workspaceServices.Workspace)); }
public void TestEjectFromImplicitCache() { ProjectCacheService cache = null; ObjectReference <Compilation> weakFirst = null, weakLast = null; FinalizerHelpers.PerformNoPinAction(() => { int total = ProjectCacheService.ImplicitCacheSize + 1; var compilations = new Compilation [total]; for (int i = 0; i < total; i++) { compilations [i] = CSharpCompilation.Create(i.ToString()); } weakFirst = ObjectReference.Create(compilations [0]); weakLast = ObjectReference.Create(compilations [total - 1]); var workspace = new AdhocWorkspace(MockHostServices.Instance, workspaceKind: WorkspaceKind.Host); cache = new ProjectCacheService(workspace, int.MaxValue); for (int i = 0; i < total; i++) { cache.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, compilations [i]); } }); weakFirst.AssertReleased(); weakLast.AssertHeld(); GC.KeepAlive(cache); }
public static async Task <ProjectCacheService> FromDescriptorAsync( ProjectCacheDescriptor pluginDescriptor, BuildManager buildManager, ILoggingService loggingService, CancellationToken cancellationToken) { var plugin = await Task.Run(() => GetPluginInstance(pluginDescriptor), cancellationToken) .ConfigureAwait(false); // TODO: Detect and use the highest verbosity from all the user defined loggers. That's tricky because right now we can't query loggers about // their verbosity levels. var loggerFactory = new Func <PluginLoggerBase>(() => new LoggingServiceToPluginLoggerAdapter(LoggerVerbosity.Normal, loggingService)); var service = new ProjectCacheService(plugin, buildManager, loggerFactory, pluginDescriptor, cancellationToken); // TODO: remove the if after we change VS to set the cache descriptor via build parameters and always call BeginBuildAsync in FromDescriptorAsync. // When running under VS we can't initialize the plugin until we evaluate a project (any project) and extract // further information (set by VS) from it required by the plugin. if (!pluginDescriptor.VsWorkaround) { await service.BeginBuildAsync(); } return(service); }
public void TestP2PReference() { var workspace = new AdhocWorkspace(); var project1 = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "proj1", "proj1", LanguageNames.CSharp); var project2 = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "proj2", "proj2", LanguageNames.CSharp, projectReferences: SpecializedCollections.SingletonEnumerable(new ProjectReference(project1.Id))); var solutionInfo = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default, projects: new ProjectInfo[] { project1, project2 }); var solution = workspace.AddSolution(solutionInfo); var instance = new object(); var weak = new WeakReference(instance); var cacheService = new ProjectCacheService(workspace, int.MaxValue); using (var cache = cacheService.EnableCaching(project2.Id)) { cacheService.CacheObjectIfCachingEnabledForKey(project1.Id, (object)null, instance); instance = null; solution = null; workspace.OnProjectRemoved(project1.Id); workspace.OnProjectRemoved(project2.Id); } // make sure p2p reference doesn't go to implicit cache CollectGarbage(); Assert.False(weak.IsAlive); }
public void TestCacheCompilationTwice() { var comp1 = CSharpCompilation.Create("1"); var comp2 = CSharpCompilation.Create("2"); var comp3 = CSharpCompilation.Create("3"); var weak3 = new WeakReference(comp3); var weak1 = new WeakReference(comp1); var cache = new ProjectCacheService(null, int.MaxValue); var key = ProjectId.CreateNewId(); var owner = new object(); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp1); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp2); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp3); // When we cache 3 again, 1 should stay in the cache cache.CacheObjectIfCachingEnabledForKey(key, owner, comp3); comp1 = null; comp2 = null; comp3 = null; CollectGarbage(); Assert.True(weak1.IsAlive); Assert.True(weak3.IsAlive); GC.KeepAlive(cache); }
public void TestEjectFromImplicitCache() { List <Compilation> compilations = new List <Compilation>(); for (int i = 0; i < ProjectCacheService.ImplicitCacheSize + 1; i++) { compilations.Add(CSharpCompilation.Create(i.ToString())); } var weakFirst = new WeakReference(compilations[0]); var weakLast = new WeakReference(compilations[compilations.Count - 1]); var cache = new ProjectCacheService(null, int.MaxValue); for (int i = 0; i < ProjectCacheService.ImplicitCacheSize + 1; i++) { cache.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, compilations[i]); } compilations = null; CollectGarbage(); Assert.False(weakFirst.IsAlive); Assert.True(weakLast.IsAlive); GC.KeepAlive(cache); }
public void TestP2PReference() { var workspace = new AdhocWorkspace(); var project1 = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "proj1", "proj1", LanguageNames.CSharp); var project2 = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "proj2", "proj2", LanguageNames.CSharp, projectReferences: SpecializedCollections.SingletonEnumerable(new ProjectReference(project1.Id))); var solutionInfo = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default, projects: new ProjectInfo[] { project1, project2 }); var solution = workspace.AddSolution(solutionInfo); var instanceTracker = ObjectReference.CreateFromFactory(() => new object()); var cacheService = new ProjectCacheService(workspace, TimeSpan.MaxValue); using (var cache = cacheService.EnableCaching(project2.Id)) { instanceTracker.UseReference(r => cacheService.CacheObjectIfCachingEnabledForKey(project1.Id, (object)null, r)); solution = null; workspace.OnProjectRemoved(project1.Id); workspace.OnProjectRemoved(project2.Id); } // make sure p2p reference doesn't go to implicit cache instanceTracker.AssertReleased(); }
public void TestEjectFromImplicitCache() { var compilations = new List <Compilation>(); for (var i = 0; i < ProjectCacheService.ImplicitCacheSize + 1; i++) { compilations.Add(CSharpCompilation.Create(i.ToString())); } var weakFirst = ObjectReference.Create(compilations[0]); var weakLast = ObjectReference.Create(compilations[compilations.Count - 1]); var workspace = new AdhocWorkspace(MockHostServices.Instance, workspaceKind: WorkspaceKind.Host); var cache = new ProjectCacheService(workspace, TimeSpan.MaxValue); for (var i = 0; i < ProjectCacheService.ImplicitCacheSize + 1; i++) { cache.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, compilations[i]); } #pragma warning disable IDE0059 // Unnecessary assignment of a value - testing weak reference to compilations compilations = null; #pragma warning restore IDE0059 // Unnecessary assignment of a value weakFirst.AssertReleased(); weakLast.AssertHeld(); GC.KeepAlive(cache); }
public void TestCacheCompilationTwice() { var comp1 = CSharpCompilation.Create("1"); var comp2 = CSharpCompilation.Create("2"); var comp3 = CSharpCompilation.Create("3"); var weak3 = ObjectReference.Create(comp3); var weak1 = ObjectReference.Create(comp1); var workspace = new AdhocWorkspace(MockHostServices.Instance, workspaceKind: WorkspaceKind.Host); var cache = new ProjectCacheService(workspace, TimeSpan.MaxValue); var key = ProjectId.CreateNewId(); var owner = new object(); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp1); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp2); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp3); // When we cache 3 again, 1 should stay in the cache cache.CacheObjectIfCachingEnabledForKey(key, owner, comp3); #pragma warning disable IDE0059 // Unnecessary assignment of a value - testing weak references to compilations comp1 = null; comp2 = null; comp3 = null; #pragma warning restore IDE0059 // Unnecessary assignment of a value weak3.AssertHeld(); weak1.AssertHeld(); GC.KeepAlive(cache); }
public void TestImplicitCacheMonitoring() { var workspace = new AdhocWorkspace(MockHostServices.Instance, workspaceKind: WorkspaceKind.Host); var cacheService = new ProjectCacheService(workspace, 10); var weak = PutObjectInImplicitCache(cacheService); var timeout = TimeSpan.FromSeconds(10); var current = DateTime.UtcNow; do { Thread.Sleep(100); CollectGarbage(); if (DateTime.UtcNow - current > timeout) { break; } }while (weak.IsAlive); // FailFast (and thereby capture a dump) to investigate what's // rooting the object. if (weak.IsAlive) { CodeAnalysis.Test.Utilities.ExceptionUtilities.FailFast(new Exception("Please investigate why the object wasn't collected!")); } GC.KeepAlive(cacheService); }
public void TestCacheCompilationTwice() { var comp1 = CSharpCompilation.Create("1"); var comp2 = CSharpCompilation.Create("2"); var comp3 = CSharpCompilation.Create("3"); var weak3 = ObjectReference.Create(comp3); var weak1 = ObjectReference.Create(comp1); var workspace = new AdhocWorkspace(MockHostServices.Instance, workspaceKind: WorkspaceKind.Host); var cache = new ProjectCacheService(workspace, int.MaxValue); var key = ProjectId.CreateNewId(); var owner = new object(); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp1); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp2); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp3); // When we cache 3 again, 1 should stay in the cache cache.CacheObjectIfCachingEnabledForKey(key, owner, comp3); comp1 = null; comp2 = null; comp3 = null; weak3.AssertHeld(); weak1.AssertHeld(); GC.KeepAlive(cache); }
private static ObjectReference <object> PutObjectInImplicitCache(ProjectCacheService cacheService) { var reference = ObjectReference.CreateFromFactory(() => new object()); reference.UseReference(r => cacheService.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, r)); return(reference); }
private static WeakReference PutObjectInImplicitCache(ProjectCacheService cacheService) { var instance = new object(); var weak = new WeakReference(instance); cacheService.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, instance); instance = null; return(weak); }
public void TestImplicitCacheMonitoring() { var workspace = new AdhocWorkspace(MockHostServices.Instance, workspaceKind: WorkspaceKind.Host); var cacheService = new ProjectCacheService(workspace, TimeSpan.FromMilliseconds(10)); var weak = PutObjectInImplicitCache(cacheService); weak.AssertReleased(); GC.KeepAlive(cacheService); }
public ActiveProjectCacheManager(IDocumentTrackingService documentTrackingService, ProjectCacheService projectCacheService) { _documentTrackingService = documentTrackingService; _projectCacheService = projectCacheService; if (documentTrackingService != null) { documentTrackingService.ActiveDocumentChanged += UpdateCache; UpdateCache(null, documentTrackingService.GetActiveDocument()); } }
public ActiveProjectCacheManager(IDocumentTrackingService documentTrackingService, ProjectCacheService projectCacheService) { _documentTrackingService = documentTrackingService; _projectCacheService = projectCacheService; if (documentTrackingService != null) { documentTrackingService.ActiveDocumentChanged += UpdateCache; UpdateCache(null, documentTrackingService.GetActiveDocument()); } }
public void TestImplicitCacheKeepsObjectAlive1() { var workspace = new AdhocWorkspace(MockHostServices.Instance, workspaceKind: WorkspaceKind.Host); var cacheService = new ProjectCacheService(workspace, TimeSpan.MaxValue); var reference = ObjectReference.CreateFromFactory(() => new object()); reference.UseReference(r => cacheService.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, r)); reference.AssertHeld(); GC.KeepAlive(cacheService); }
public void TestImplicitCacheKeepsObjectAlive1() { var cacheService = new ProjectCacheService(null, int.MaxValue); var instance = new object(); var weak = new WeakReference(instance); cacheService.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, instance); instance = null; CollectGarbage(); Assert.True(weak.IsAlive); GC.KeepAlive(cacheService); }
private void Test(Action<IProjectCacheHostService, ProjectId, ICachedObjectOwner, ObjectReference> action) { // Putting cacheService.CreateStrongReference in a using statement // creates a temporary local that isn't collected in Debug builds // Wrapping it in a lambda allows it to get collected. var cacheService = new ProjectCacheService(null, int.MaxValue); var projectId = ProjectId.CreateNewId(); var owner = new Owner(); var instance = new ObjectReference(); action(cacheService, projectId, owner, instance); }
private static void Test(Action <IProjectCacheHostService, ProjectId, ICachedObjectOwner, ObjectReference <object> > action) { // Putting cacheService.CreateStrongReference in a using statement // creates a temporary local that isn't collected in Debug builds // Wrapping it in a lambda allows it to get collected. var cacheService = new ProjectCacheService(null, TimeSpan.MaxValue); var projectId = ProjectId.CreateNewId(); var owner = new Owner(); var instance = ObjectReference.CreateFromFactory(() => new object()); action(cacheService, projectId, owner, instance); }
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { var service = new ProjectCacheService(workspaceServices.Workspace, ImplicitCacheTimeoutInMS); // Also clear the cache when the solution is cleared or removed. workspaceServices.Workspace.WorkspaceChanged += (s, e) => { if (e.Kind == WorkspaceChangeKind.SolutionCleared || e.Kind == WorkspaceChangeKind.SolutionRemoved) { service.ClearImplicitCache(); } }; return service; }
private static IWorkspaceService GetMiscProjectCache(HostWorkspaceServices workspaceServices) { if (workspaceServices.Workspace.Kind != WorkspaceKind.Host) { return new ProjectCacheService(workspaceServices.Workspace); } var projectCacheService = new ProjectCacheService(workspaceServices.Workspace, ImplicitCacheTimeoutInMS); // Also clear the cache when the solution is cleared or removed. workspaceServices.Workspace.WorkspaceChanged += (s, e) => { if (e.Kind == WorkspaceChangeKind.SolutionCleared || e.Kind == WorkspaceChangeKind.SolutionRemoved) { projectCacheService.ClearImplicitCache(); } }; return projectCacheService; }
public static async Task <ProjectCacheService> FromDescriptorAsync( ProjectCacheDescriptor pluginDescriptor, BuildManager buildManager, ILoggingService loggingService, CancellationToken cancellationToken) { var plugin = await Task.Run(() => GetPluginInstance(pluginDescriptor), cancellationToken) .ConfigureAwait(false); var service = new ProjectCacheService(plugin, buildManager, loggingService, pluginDescriptor, cancellationToken); // TODO: remove the if after we change VS to set the cache descriptor via build parameters and always call BeginBuildAsync in FromDescriptorAsync. // When running under VS we can't initialize the plugin until we evaluate a project (any project) and extract // further information (set by VS) from it required by the plugin. if (!pluginDescriptor.VsWorkaround) { await service.BeginBuildAsync(); } return(service); }
public void TestImplicitCacheMonitoring() { var cacheService = new ProjectCacheService(null, 10, forceCleanup: true); var weak = PutObjectInImplicitCache(cacheService); var timeout = TimeSpan.FromSeconds(10); var current = DateTime.UtcNow; do { Thread.Sleep(100); CollectGarbage(); if (DateTime.UtcNow - current > timeout) { break; } }while (weak.IsAlive); Assert.False(weak.IsAlive); GC.KeepAlive(cacheService); }
public void TestP2PReference() { var workspace = new AdhocWorkspace(); var project1 = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "proj1", "proj1", LanguageNames.CSharp); var project2 = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "proj2", "proj2", LanguageNames.CSharp, projectReferences: SpecializedCollections.SingletonEnumerable(new ProjectReference(project1.Id))); var solutionInfo = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default, projects: new ProjectInfo[] { project1, project2 }); var solution = workspace.AddSolution(solutionInfo); var instance = new object(); var weak = new WeakReference(instance); var cacheService = new ProjectCacheService(workspace, int.MaxValue); using (var cache = cacheService.EnableCaching(project2.Id)) { cacheService.CacheObjectIfCachingEnabledForKey(project1.Id, (object)null, instance); instance = null; solution = null; workspace.OnProjectRemoved(project1.Id); workspace.OnProjectRemoved(project2.Id); } // make sure p2p reference doesnt go to implicit cache CollectGarbage(); Assert.False(weak.IsAlive); }
public ImplicitCacheMonitor(ProjectCacheService owner, int backOffTimeSpanInMS) : base(AggregateAsynchronousOperationListener.CreateEmptyListener(), backOffTimeSpanInMS, CancellationToken.None) { _owner = owner; _gate = new SemaphoreSlim(0); Start(); }
public void TestImplicitCacheKeepsObjectAlive1() { var cacheService = new ProjectCacheService(null, int.MaxValue); var instance = new object(); var weak = new WeakReference(instance); cacheService.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, instance); instance = null; CollectGarbage(); Assert.True(weak.IsAlive); GC.KeepAlive(cacheService); }
public void TestImplicitCacheMonitoring() { var cacheService = new ProjectCacheService(null, 10, forceCleanup: true); var weak = PutObjectInImplicitCache(cacheService); var timeout = TimeSpan.FromSeconds(10); var current = DateTime.UtcNow; do { Thread.Sleep(100); CollectGarbage(); if (DateTime.UtcNow - current > timeout) { break; } } while (weak.IsAlive); Assert.False(weak.IsAlive); GC.KeepAlive(cacheService); }
private static WeakReference PutObjectInImplicitCache(ProjectCacheService cacheService) { var instance = new object(); var weak = new WeakReference(instance); cacheService.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, instance); instance = null; return weak; }
public void TestCacheCompilationTwice() { var comp1 = CSharpCompilation.Create("1"); var comp2 = CSharpCompilation.Create("2"); var comp3 = CSharpCompilation.Create("3"); var weak3 = new WeakReference(comp3); var weak1 = new WeakReference(comp1); var cache = new ProjectCacheService(null, int.MaxValue); var key = ProjectId.CreateNewId(); var owner = new object(); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp1); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp2); cache.CacheObjectIfCachingEnabledForKey(key, owner, comp3); // When we cache 3 again, 1 should stay in the cache cache.CacheObjectIfCachingEnabledForKey(key, owner, comp3); comp1 = null; comp2 = null; comp3 = null; CollectGarbage(); Assert.True(weak1.IsAlive); Assert.True(weak3.IsAlive); GC.KeepAlive(cache); }
public void TestImplicitCacheMonitoring() { var cacheService = new ProjectCacheService(null, 10, forceCleanup: true); var weak = PutObjectInImplicitCache(cacheService); var timeout = TimeSpan.FromSeconds(10); var current = DateTime.UtcNow; do { Thread.Sleep(100); CollectGarbage(); if (DateTime.UtcNow - current > timeout) { break; } } while (weak.IsAlive); // FailFast (and thereby capture a dump) to investigate what's // rooting the object. if (weak.IsAlive) { CodeAnalysis.Test.Utilities.ExceptionUtilities.FailFast(new Exception("Please investigate why the object wasn't collected!")); } GC.KeepAlive(cacheService); }
public void TestEjectFromImplicitCache() { List<Compilation> compilations = new List<Compilation>(); for (int i = 0; i < ProjectCacheService.ImplicitCacheSize + 1; i++) { compilations.Add(CSharpCompilation.Create(i.ToString())); } var weakFirst = new WeakReference(compilations[0]); var weakLast = new WeakReference(compilations[compilations.Count - 1]); var cache = new ProjectCacheService(null, int.MaxValue); for (int i = 0; i < ProjectCacheService.ImplicitCacheSize + 1; i++) { cache.CacheObjectIfCachingEnabledForKey(ProjectId.CreateNewId(), (object)null, compilations[i]); } compilations = null; CollectGarbage(); Assert.False(weakFirst.IsAlive); Assert.True(weakLast.IsAlive); GC.KeepAlive(cache); }