/// <summary> /// Checks the completed connection objects. /// </summary> /// <returns>True if everything completed normally and false if there were any client disconnections.</returns> private bool CheckConnectionTask(List <Task <ConnectionData> > connectionList, ref TimeSpan?keepAlive, ref bool isKeepAliveDefault) { var allFine = true; 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, ref keepAlive, ref isKeepAliveDefault); if (connectionData.CompletionReason == CompletionReason.ClientDisconnect || connectionData.CompletionReason == CompletionReason.ClientException) { allFine = false; } } if (processedCount > 0) { _diagnosticListener.ConnectionCompleted(processedCount); } return(allFine); }
/// <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. /// </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 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"); } }