private void LogWriteInfo(int status, Exception error) { if (error == null) { _log.ConnectionWriteCallback(_connectionId, status); } else { // Log connection resets at a lower (Debug) level. if (status == LibuvConstants.ECANCELED) { // Connection was aborted. } else if (LibuvConstants.IsConnectionReset(status)) { _log.ConnectionReset(_connectionId); } else { _log.ConnectionError(_connectionId, error); } } }
private async Task StartCore() { try { OutputConsumer = new LibuvOutputConsumer(Output, Thread, _socket, ConnectionId, Log); StartReading(); Exception inputError = null; Exception outputError = null; try { // This *must* happen after socket.ReadStart // The socket output consumer is the only thing that can close the connection. If the // output pipe is already closed by the time we start then it's fine since, it'll close gracefully afterwards. await OutputConsumer.WriteOutputAsync(); } catch (UvException ex) { // The connection reset/error has already been logged by LibuvOutputConsumer if (ex.StatusCode == LibuvConstants.ECANCELED) { // Connection was aborted. } else if (LibuvConstants.IsConnectionReset(ex.StatusCode)) { // Don't cause writes to throw for connection resets. inputError = new ConnectionResetException(ex.Message, ex); } else { // This is unexpected. Log.ConnectionError(ConnectionId, ex); inputError = ex; outputError = ex; } } finally { inputError ??= _abortReason ?? new ConnectionAbortedException("The libuv transport's send loop completed gracefully."); // Now, complete the input so that no more reads can happen Input.Complete(inputError); Output.Complete(outputError); // Make sure it isn't possible for a paused read to resume reading after calling uv_close // on the stream handle Input.CancelPendingFlush(); // Send a FIN Log.ConnectionWriteFin(ConnectionId, inputError.Message); // We're done with the socket now _socket.Dispose(); // Ensure this always fires FireConnectionClosed(); await _waitForConnectionClosedTcs.Task; } } catch (Exception e) { Log.LogCritical(0, e, $"{nameof(LibuvConnection)}.{nameof(Start)}() {ConnectionId}"); } }