/// <summary> /// Checks the completed connection objects. /// </summary> /// <returns>False if the server needs to begin shutting down</returns> private void HandleCompletedConnections() { var shutdown = false; var processedCount = 0; var i = 0; while (i < _connectionList.Count) { var current = _connectionList[i]; if (!current.IsCompleted) { i++; continue; } _connectionList.RemoveAt(i); processedCount++; var connectionData = current.Result; ChangeKeepAlive(connectionData.KeepAlive); switch (connectionData.CompletionReason) { case CompletionReason.CompilationCompleted: case CompletionReason.CompilationNotStarted: CompilerServerLogger.Log("Client completed"); // These are all normal shutdown states. Nothing to do here. break; case CompletionReason.ClientDisconnect: // Have to assume the worst here which is user pressing Ctrl+C at the command line and // hence wanting all compilation to end. CompilerServerLogger.LogError("Unexpected client disconnect. Shutting down server"); shutdown = true; break; case CompletionReason.ClientException: CompilerServerLogger.LogError($"Unexpected client exception. Shutting down server"); shutdown = true; break; case CompletionReason.ClientShutdownRequest: CompilerServerLogger.Log($"Client requesting server shutdown"); shutdown = true; break; default: throw new InvalidOperationException($"Unexpected enum value {connectionData.CompletionReason}"); } _diagnosticListener.ConnectionCompleted(connectionData.CompletionReason); } if (shutdown) { CompilerServerLogger.Log($"Shutting down server"); _state = State.ShuttingDown; } }
/// <summary> /// Checks the completed connection objects and updates the server state based on their /// results. /// </summary> private void HandleCompletedConnections() { var shutdown = false; var processedCount = 0; var i = 0; while (i < _connectionList.Count) { var current = _connectionList[i]; if (!current.IsCompleted) { i++; continue; } _connectionList.RemoveAt(i); processedCount++; var completionData = current.Result; switch (completionData.Reason) { case CompletionReason.RequestCompleted: CompilerServerLogger.Log("Client request completed"); if (completionData.NewKeepAlive is { } keepAlive) { CompilerServerLogger.Log($"Client changed keep alive to {keepAlive}"); ChangeKeepAlive(keepAlive); } if (completionData.ShutdownRequest) { CompilerServerLogger.Log("Client requested shutdown"); shutdown = true; } // These are all normal shutdown states. Nothing to do here. break; case CompletionReason.RequestError: CompilerServerLogger.LogError("Client request failed"); shutdown = true; break; default: CompilerServerLogger.LogError("Unexpected enum value"); shutdown = true; break; } _diagnosticListener.ConnectionCompleted(completionData); } if (shutdown) { CompilerServerLogger.Log($"Shutting down server"); _state = State.ShuttingDown; } }
/// <summary> /// Checks the completed connection objects and updates the server state based on their /// results. /// </summary> private void HandleCompletedConnections() { var shutdown = false; var i = 0; while (i < _connectionList.Count) { var current = _connectionList[i]; if (!current.IsCompleted) { i++; continue; } _connectionList.RemoveAt(i); // These task should never fail. Unexpected errors will be caught and translated into // a RequestError message Debug.Assert(current.Status == TaskStatus.RanToCompletion); var completionData = current.Result; switch (completionData.Reason) { case CompletionReason.RequestCompleted: CompilerServerLogger.Log("Client request completed"); if (completionData.NewKeepAlive is { } keepAlive) { CompilerServerLogger.Log($"Client changed keep alive to {keepAlive}"); ChangeKeepAlive(keepAlive); } if (completionData.ShutdownRequest) { CompilerServerLogger.Log("Client requested shutdown"); shutdown = true; } break; case CompletionReason.RequestError: CompilerServerLogger.LogError("Client request failed"); shutdown = true; break; default: CompilerServerLogger.LogError("Unexpected enum value"); shutdown = true; break; } _diagnosticListener.ConnectionCompleted(completionData); } if (shutdown) { ChangeToShuttingDown("Error handling client connection"); } }
private static bool CheckCore(string baseDirectory, IEnumerable <CommandLineAnalyzerReference> analyzerReferences, IAnalyzerAssemblyLoader loader) { var resolvedPaths = new List <string>(); foreach (var analyzerReference in analyzerReferences) { string?resolvedPath = FileUtilities.ResolveRelativePath(analyzerReference.FilePath, basePath: null, baseDirectory: baseDirectory, searchPaths: SpecializedCollections.EmptyEnumerable <string>(), fileExists: File.Exists); if (resolvedPath != null) { resolvedPath = FileUtilities.TryNormalizeAbsolutePath(resolvedPath); if (resolvedPath != null) { resolvedPaths.Add(resolvedPath); } } // Don't worry about paths we can't resolve. The compiler will report an error for that later. } // Register analyzers and their dependencies upfront, // so that assembly references can be resolved: foreach (var resolvedPath in resolvedPaths) { loader.AddDependencyLocation(resolvedPath); } // Load all analyzer assemblies: var loadedAssemblies = new List <Assembly>(); foreach (var resolvedPath in resolvedPaths) { loadedAssemblies.Add(loader.LoadFromPath(resolvedPath)); } // Third, check that the MVIDs of the files on disk match the MVIDs of the loaded assemblies. for (int i = 0; i < resolvedPaths.Count; i++) { var resolvedPath = resolvedPaths[i]; var loadedAssembly = loadedAssemblies[i]; var resolvedPathMvid = AssemblyUtilities.ReadMvid(resolvedPath); var loadedAssemblyMvid = loadedAssembly.ManifestModule.ModuleVersionId; if (resolvedPathMvid != loadedAssemblyMvid) { CompilerServerLogger.LogError($"Analyzer assembly {resolvedPath} has MVID '{resolvedPathMvid}' but loaded assembly '{loadedAssembly.FullName}' has MVID '{loadedAssemblyMvid}'."); return(false); } } return(true); }