internal virtual async ValueTask <((long, long), string message)> ReceiveGoAwayFrameAsync() { byte frameType = _transceiver.Endpoint.Protocol == Protocol.Ice1 ? (byte)Ice1Definitions.FrameType.CloseConnection : (byte)Ice2Definitions.FrameType.GoAway; (ArraySegment <byte> data, bool fin) = await ReceiveFrameAsync(frameType, CancellationToken.None).ConfigureAwait(false); if (!fin) { throw new InvalidDataException($"expected end of stream after GoAway frame"); } if (_transceiver.Endpoint.Communicator.TraceLevels.Protocol >= 1) { TraceFrame(data, frameType); } if (_transceiver.Endpoint.Protocol == Protocol.Ice1) { // LastResponseStreamId contains the stream ID of the last received response. We make sure to return // this stream ID to ensure the request with this stream ID will complete successfully in case the // close connection message is received shortly after the response and potentially processed before // due to the thread scheduling. return((_transceiver.LastResponseStreamId, 0), "connection gracefully closed by peer"); } else { var istr = new InputStream(data, Ice2Definitions.Encoding); return(((long)istr.ReadVarULong(), (long)istr.ReadVarULong()), istr.ReadString()); } }
internal RetryPolicy(InputStream istr) { Retryable = istr.ReadRetryable(); Delay = Retryable == Retryable.AfterDelay ? TimeSpan.FromMilliseconds(istr.ReadVarULong()) : TimeSpan.Zero; }