private static Messaging CreateMessagingHeader(AS4Message message) { object ToGeneralMessageUnit(MessageUnit u) { switch (u) { case UserMessage um: return(UserMessageMap.Convert(um)); case Receipt r: return(ReceiptMap.Convert(r)); case Error e: return(ErrorMap.Convert(e)); case PullRequest pr: return(PullRequestMap.Convert(pr)); default: throw new NotSupportedException( $"AS4Message contains unkown MessageUnit of type: {u.GetType()}"); } } var messagingHeader = new Messaging { SecurityId = message.SigningId.HeaderSecurityId, MessageUnits = message.MessageUnits.Select(ToGeneralMessageUnit).ToArray() }; if (message.IsMultiHopMessage) { messagingHeader.role = Constants.Namespaces.EbmsNextMsh; messagingHeader.mustUnderstand1 = true; messagingHeader.mustUnderstand1Specified = true; } return(messagingHeader); }
public Task ReadAsync(IMemoryOwner <byte> buffer, ErrorMap errorMap = null) { EnsureNotDisposed(); var header = buffer.Memory.Span.CreateHeader(errorMap, out var errorCode); return(ReadAsync(buffer, header, errorCode)); }
internal static OperationHeader CreateHeader(this Span <byte> buffer, ErrorMap errorMap, out ErrorCode errorCode) { // This overload is necessary because the compiler won't apply implicit casting when finding extension methods, // so it avoids the need for explicit casting to find the extension method below. return(CreateHeader((ReadOnlySpan <byte>)buffer, errorMap, out errorCode)); }
public void Read(IMemoryOwner <byte> buffer, ErrorMap errorMap = null) { EnsureNotDisposed(); var header = buffer.Memory.Span.CreateHeader(errorMap, out var errorCode); Read(buffer, header, errorCode); }
public async Task When_Status_Indicates_Failure_Context_Is_Populated() { var errorMap = new ErrorMap(JsonConvert.DeserializeObject <ErrorMapDto>(ResourceHelper.ReadResource("kv-error-map.json"))); var mockConnection = new Mock <IConnection>(); var mockConnectionPool = new Mock <IConnectionPool>(); mockConnectionPool .Setup(m => m.SendAsync(It.IsAny <IOperation>(), It.IsAny <CancellationToken>())) .Returns((IOperation operation, CancellationToken _) => operation.SendAsync(mockConnection.Object)); var mockConnectionPoolFactory = new Mock <IConnectionPoolFactory>(); mockConnectionPoolFactory .Setup(m => m.Create(It.IsAny <ClusterNode>())) .Returns(mockConnectionPool.Object); var node = new ClusterNode(new ClusterContext(new CancellationTokenSource(), new ClusterOptions()), mockConnectionPoolFactory.Object, new Mock <ILogger <ClusterNode> >().Object, new DefaultObjectPool <OperationBuilder>(new OperationBuilderPoolPolicy()), new Mock <ICircuitBreaker>().Object, new Mock <ISaslMechanismFactory>().Object, new Mock <IRedactor>().Object, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11210), BucketType.Couchbase, new NodeAdapter { Hostname = "127.0.0.1" }, NullRequestTracer.Instance) { ErrorMap = errorMap }; var insert = new FakeOperation(OpCode.Add, ResponseStatus.KeyExists) { SName = "TheScope", CName = "TheCollection" }; try { await node.ExecuteOp(insert, CancellationToken.None).ConfigureAwait(false); } catch (DocumentExistsException e) { var context = e.Context as KeyValueErrorContext; Assert.NotNull(e.Context); var message = "KV Error: {Name=\"KEY_EEXISTS\", Description=\"key already exists, or CAS mismatch\", Attributes=\"item-only\"}"; Assert.Equal(message, e.Context.Message); Assert.Equal("TheScope", context.ScopeName); Assert.Equal("TheCollection", context.CollectionName); Assert.NotEqual("0", context.ClientContextId); } }
public void AddToErrorMap(string path, string error) { if (ErrorMap.ContainsKey(path)) { ErrorMap[path] = error; } else { ErrorMap.Add(path, error); } }
public Property Mapping_Error_Back_And_Forth_Stays_The_Same(Error error) { // Act var result = ErrorMap.Convert(ErrorMap.Convert(error), error.MultiHopRouting); // Assert return(error.MessageId.Equals(result.MessageId).Label("equal message id") .And(error.RefToMessageId.Equals(result.RefToMessageId).Label("equal ref to message id")) .And(error.ErrorLines.SequenceEqual(result.ErrorLines).Label("equal error lines")) .And(error.MultiHopRouting.Equals(result.MultiHopRouting).Label("equal routing usermessage"))); }
public void Result_Has_Failure_Status_If_ErrorMap_Available() { const string codeString = "2c"; // 44 var code = short.Parse(codeString, NumberStyles.HexNumber); var errorCode = new ErrorCode { Name = "test" }; var errorMap = new ErrorMap { Version = 1, Revision = 1, Errors = new Dictionary <string, ErrorCode> { { codeString, errorCode } } }; var converter = new DefaultConverter(); var responseBytes = new byte[24]; converter.FromByte((byte)Magic.Response, responseBytes, HeaderIndexFor.Magic); converter.FromInt16(code, responseBytes, HeaderIndexFor.Status); var mockConnection = new Mock <IConnection>(); mockConnection.Setup(x => x.IsConnected).Returns(true); mockConnection.Setup(x => x.Send(It.IsAny <byte[]>())).Returns(responseBytes); var mockConnectionPool = new Mock <IConnectionPool>(); mockConnectionPool.Setup(x => x.Acquire()).Returns(mockConnection.Object); mockConnectionPool.SetupGet(x => x.Configuration).Returns(new PoolConfiguration { ClientConfiguration = new ClientConfiguration { Tracer = NullTracer.Instance } }); mockConnectionPool.Setup(x => x.Connections).Returns(new List <IConnection> { mockConnection.Object }); var service = new PooledIOService(mockConnectionPool.Object) { ErrorMap = errorMap }; var result = service.Execute(new FakeOperationWithRequiredKey("key", null, new DefaultTranscoder(), 0, 0)); Assert.AreEqual(ResponseStatus.Failure, result.Status); Assert.AreEqual(errorCode.ToString(), result.Message); }
/// <summary> /// Send request to server to try and enable server features. /// </summary> /// <param name="connection">The connection.</param> protected void EnableServerFeatures(IConnection connection) { var features = new List <short> { (short)ServerFeatures.SubdocXAttributes, (short)ServerFeatures.SelectBucket }; if (ConnectionPool.Configuration.UseEnhancedDurability) { features.Add((short)ServerFeatures.MutationSeqno); } if (ConnectionPool.Configuration.UseKvErrorMap) { features.Add((short)ServerFeatures.XError); } var transcoder = new DefaultTranscoder(); var result = Execute(new Hello(features.ToArray(), transcoder, 0, 0), connection); if (result.Success) { SupportsEnhancedDurability = result.Value.Contains((short)ServerFeatures.MutationSeqno); SupportsSubdocXAttributes = result.Value.Contains((short)ServerFeatures.SubdocXAttributes); SupportsEnhancedAuthentication = result.Value.Contains((short)ServerFeatures.SelectBucket); SupportsKvErrorMap = result.Value.Contains((short)ServerFeatures.XError); ConnectionPool.SupportsEnhancedAuthentication = SupportsEnhancedAuthentication; Log.Info("SupportsEnhancedDurability={0}", SupportsEnhancedDurability); Log.Info("SupportsSubdocXAttributes={0}", SupportsSubdocXAttributes); Log.Info("SupportsEnhancedAuthentication={0}", SupportsEnhancedAuthentication); Log.Info("SupportsKvErrorMap={0}", SupportsKvErrorMap); if (SupportsKvErrorMap) { var errorMapResult = Execute(new GetErrorMap(transcoder, 0), connection); if (!errorMapResult.Success) { throw new Exception("Error retrieving error map. Cluster indicated it was available."); } ErrorMap = errorMapResult.Value; } } else { LogFailedHelloOperation(result); } }
/// <summary> /// 获取错误代码 /// 参见:http://msdn.microsoft.com/zh-cn/library/bb762164(v=vs.85).aspx /// </summary> /// <param name="n"></param> /// <returns></returns> public static string GetErrorString(int n) { if (ErrorMap == null) { InitErrorMap(); } string code = n.ToString("X").ToUpper(); string message = null; if (ErrorMap.TryGetValue(code, out message)) { return(message); } return(code); }
private static string GetErrorDescription(HRESULT hr) { if (_detailedErrorMap.TryGetValue(hr, out string value)) { return($"Unknown exception occured with HRESULT {hr:X8} - \"" + $"{value}\""); } else if (ErrorMap.TryGetValue(hr, out value)) { return($"Unknown exception occured with HRESULT {hr:X8} - \"" + $"{value}\""); } else { return($"Unknown exception occured with HRESULT {hr:X8}"); } }
private static SignalMessage ConvertSignalMessageFromXml(Xml.SignalMessage signalMessage, Maybe <RoutingInputUserMessage> routing) { if (signalMessage.Error != null) { return(ErrorMap.Convert(signalMessage, routing)); } if (signalMessage.PullRequest != null) { return(PullRequestMap.Convert(signalMessage)); } if (signalMessage.Receipt != null) { return(ReceiptMap.Convert(signalMessage, routing)); } throw new NotSupportedException("Unable to map Xml.SignalMessage to SignalMessage"); }
internal static OperationHeader CreateHeader(this byte[] buffer, ErrorMap errorMap, out ErrorCode errorCode) { if (buffer == null || buffer.Length < OperationHeader.Length) { errorCode = null; return(new OperationHeader { Status = ResponseStatus.None }); } int keyLength, framingExtrasLength; var magic = (Magic)Converter.ToByte(buffer, HeaderOffsets.Magic); if (magic == Magic.AltResponse) { framingExtrasLength = Converter.ToByte(buffer, HeaderOffsets.FramingExtras); keyLength = Converter.ToByte(buffer, HeaderOffsets.AltKeyLength); } else { framingExtrasLength = 0; keyLength = Converter.ToInt16(buffer, HeaderOffsets.KeyLength); } var statusCode = Converter.ToInt16(buffer, HeaderOffsets.Status); var status = GetResponseStatus(statusCode, errorMap, out errorCode); return(new OperationHeader { Magic = (byte)magic, OpCode = Converter.ToByte(buffer, HeaderOffsets.Opcode).ToOpCode(), FramingExtrasLength = framingExtrasLength, KeyLength = keyLength, ExtrasLength = Converter.ToByte(buffer, HeaderOffsets.ExtrasLength), DataType = (DataType)Converter.ToByte(buffer, HeaderOffsets.Datatype), Status = status, BodyLength = Converter.ToInt32(buffer, HeaderOffsets.Body), Opaque = Converter.ToUInt32(buffer, HeaderOffsets.Opaque), Cas = Converter.ToUInt64(buffer, HeaderOffsets.Cas) }); }
public void Result_Has_UnknownError_Status_If_ErrorMap_Not_Available() { const string codeString = "2c"; // 44 var code = short.Parse(codeString, NumberStyles.HexNumber); var errorCode = new ErrorCode { Name = "test" }; var errorMap = new ErrorMap { Version = 1, Revision = 1, Errors = new Dictionary <string, ErrorCode>() }; var converter = new DefaultConverter(); var responseBytes = new byte[24]; converter.FromInt16(code, responseBytes, HeaderIndexFor.Status); var mockConnection = new Mock <IConnection>(); mockConnection.Setup(x => x.IsConnected).Returns(true); mockConnection.Setup(x => x.Send(It.IsAny <byte[]>())).Returns(responseBytes); var mockConnectionPool = new Mock <IConnectionPool>(); mockConnectionPool.Setup(x => x.Acquire()).Returns(mockConnection.Object); mockConnectionPool.SetupGet(x => x.Configuration).Returns(new PoolConfiguration()); var service = new MultiplexingIOService(mockConnectionPool.Object) { ErrorMap = errorMap }; var result = service.Execute(new FakeOperationWithRequiredKey("key", null, new DefaultTranscoder(), 0, 0)); Assert.AreEqual(ResponseStatus.UnknownError, result.Status); Assert.AreEqual(converter.ToString(responseBytes, 0, 24), result.Message); }
internal static ResponseStatus GetResponseStatus(short code, ErrorMap errorMap, out ErrorCode errorCode) { var status = (ResponseStatus)code; // Is it a known response status? if (!ValidResponseStatuses.Contains(status)) { status = ResponseStatus.UnknownError; } // If available, try and use the error map to get more details if (errorMap != null) { errorMap.TryGetGetErrorCode(code, out errorCode); } else { errorCode = null;//make the compiler happy } return(status); }
public void SendAsync(byte[] buffer, Func <SocketAsyncState, Task> callback, ISpan dispatchSpan, ErrorMap errorMap) { throw new NotImplementedException(); }
public virtual Task SendAsync(byte[] request, Func <SocketAsyncState, Task> callback, ISpan dispatchSpan, ErrorMap errorMap) { throw new NotImplementedException(); }
public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback, ISpan span, ErrorMap errorMap) { ExceptionDispatchInfo capturedException = null; SocketAsyncState state = null; try { var opaque = Converter.ToUInt32(request, HeaderIndexFor.Opaque); state = new SocketAsyncState { Data = MemoryStreamFactory.GetMemoryStream(), Opaque = opaque, Buffer = request, Completed = callback, DispatchSpan = span, CorrelationId = CreateCorrelationId(opaque), ErrorMap = errorMap }; await _sslStream.WriteAsync(request, 0, request.Length).ContinueOnAnyContext(); state.SetIOBuffer(BufferAllocator.GetBuffer()); state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, state.BufferLength).ContinueOnAnyContext(); //write the received buffer to the state obj await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived).ContinueOnAnyContext(); state.BodyLength = Converter.ToInt32(state.Buffer, state.BufferOffset + HeaderIndexFor.BodyLength); while (state.BytesReceived < state.BodyLength + 24) { var bufferLength = state.BufferLength - state.BytesSent < state.BufferLength ? state.BufferLength - state.BytesSent : state.BufferLength; state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, bufferLength).ContinueOnAnyContext(); await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived - (int)state.Data.Length).ContinueOnAnyContext(); } await callback(state).ContinueOnAnyContext(); } catch (Exception e) { IsDead = true; capturedException = ExceptionDispatchInfo.Capture(e); } finally { ConnectionPool.Release(this); if (state.IOBuffer != null) { BufferAllocator.ReleaseBuffer(state.IOBuffer); } } if (capturedException != null) { var sourceException = capturedException.SourceException; if (state == null) { await callback(new SocketAsyncState { Exception = capturedException.SourceException, Status = (sourceException is SocketException) ? ResponseStatus.TransportFailure : ResponseStatus.ClientFailure }).ContinueOnAnyContext(); } else { state.Exception = sourceException; await state.Completed(state).ContinueOnAnyContext(); Log.Debug(sourceException); } } }
public void SendAsync(byte[] buffer, Func <SocketAsyncState, Task> callback, ISpan dispatchSpan, ErrorMap errorMap) { var state = new SocketAsyncState { Data = new MemoryStream(_responseBytes), Opaque = Converter.ToUInt32(buffer, HeaderIndexFor.Opaque) }; callback(state); }
public async Task ExecuteOp(IOperation op, CancellationToken token = default(CancellationToken), TimeSpan?timeout = null) { Log.LogDebug("Executing op {0} with key {1} and opaque {2}", op.OpCode, op.Key, op.Opaque); // wire up op's completed function var tcs = new TaskCompletionSource <IMemoryOwner <byte> >(); op.Completed = state => { if (state.Status == ResponseStatus.Success) { tcs.TrySetResult(state.ExtractData()); } else if (state.Status == ResponseStatus.VBucketBelongsToAnotherServer) { tcs.TrySetResult(state.ExtractData()); } else { ErrorMap.TryGetGetErrorCode((short)state.Status, out ErrorCode errorCode); tcs.TrySetException(state.ThrowException(errorCode)); } return(tcs.Task); }; CancellationTokenSource cts = null; try { if (token == CancellationToken.None) { cts = CancellationTokenSource.CreateLinkedTokenSource(token); cts.CancelAfter(timeout.HasValue && timeout != TimeSpan.Zero ? timeout.Value : DefaultTimeout); token = cts.Token; } using (token.Register(() => { if (tcs.Task.Status != TaskStatus.RanToCompletion) { tcs.TrySetCanceled(); } }, useSynchronizationContext: false)) { await CheckConnectionAsync(); await op.SendAsync(Connection).ConfigureAwait(false); var bytes = await tcs.Task.ConfigureAwait(false); await op.ReadAsync(bytes).ConfigureAwait(false); var status = op.Header.Status; if (status == ResponseStatus.VBucketBelongsToAnotherServer) { var config = op.GetConfig(_transcoder); _context.PublishConfig(config); } Log.LogDebug("Completed executing op {0} with key {1} and opaque {2}", op.OpCode, op.Key, op.Opaque); } } catch (OperationCanceledException e) { if (!e.CancellationToken.IsCancellationRequested) { //oddly IsCancellationRequested is false when timed out throw new TimeoutException(); } } finally { //clean up the token if we used a default token cts?.Dispose(); } }
public override void SendAsync(byte[] buffer, Func <SocketAsyncState, Task> callback, ISpan span, ErrorMap errorMap) { SocketAsyncState state = null; try { var opaque = Converter.ToUInt32(buffer, HeaderIndexFor.Opaque); state = new SocketAsyncState { Data = MemoryStreamFactory.GetMemoryStream(), Opaque = opaque, Buffer = buffer, Completed = callback, SendOffset = _eventArgs.Offset, DispatchSpan = span, CorrelationId = CreateCorrelationId(opaque), ErrorMap = errorMap }; _eventArgs.UserToken = state; Log.Debug("Sending {0} with {1} on server {2}", state.Opaque, Identity, EndPoint); //set the buffer var bufferLength = buffer.Length < Configuration.BufferSize ? buffer.Length : Configuration.BufferSize; _eventArgs.SetBuffer(state.SendOffset, bufferLength); Buffer.BlockCopy(buffer, 0, _eventArgs.Buffer, state.SendOffset, bufferLength); //Send the request if (!Socket.SendAsync(_eventArgs)) { OnCompleted(Socket, _eventArgs); } } catch (Exception e) { if (state == null) { callback(new SocketAsyncState { Exception = e, Status = (e is SocketException) ? ResponseStatus.TransportFailure : ResponseStatus.ClientFailure }); } else { state.Exception = e; state.Completed(state); Log.Debug(e); } } }
public static KeyValueException Create(ResponseStatus status, Exception innerException = null, string message = null, ErrorMap errorMap = null) { return(new KeyValueException(message, innerException) { ErrorMap = errorMap, ResponseStatus = status }); }
private void RunTaskAsync() { try { ProcessedObjects = 0; ObjectsCount = 0; ErrorMap.Clear(); List <string> allLinkedFiles = new List <string>(); foreach (string path in SrcFiles) { if (File.Exists(path)) { List <String> linkedFiles = _support.GetChildFiles(path, TaskType); if (linkedFiles != null && linkedFiles.Count > 0) { var linkedFilesLowercase = (from s in linkedFiles select s.ToLowerInvariant()).ToList(); allLinkedFiles.AddRange(linkedFilesLowercase); } } } List <string> srcFilesClone = new List <string>(SrcFiles); foreach (string srcFile in srcFilesClone) { if (allLinkedFiles.Contains(srcFile.ToLowerInvariant())) { SrcFiles.Remove(srcFile); } } foreach (string path in SrcFiles) { if (Directory.Exists(path)) { List <string> entries = PathUtils.EnumFileSystemEntries(path, "*", SearchOption.AllDirectories); if (entries != null && entries.Count > 0) { ObjectsCount += entries.Count; } } else { ObjectsCount++; } } ObjectsCount += allLinkedFiles.Count; FireTaskProgress(ProgressEventType.Started, string.Empty, UpdateProgressData.Empty); _currentPath = string.Empty; _timer.Start(); try { foreach (string path in SrcFiles) { _currentPath = path; FireTaskProgress(ProgressEventType.Progress, path, UpdateProgressData.Empty); switch (TaskType) { case FileTaskType.Copy: CopyObject(path); break; case FileTaskType.Move: MoveObject(path); break; case FileTaskType.Delete: DeleteObject(path); break; } } } catch (TaskInterruptedException) { FireTaskProgress(ProgressEventType.Aborted, string.Empty, UpdateProgressData.Empty); return; } finally { _timer.Stop(); _currentPath = string.Empty; } } catch (Exception ex) { Logger.LogException(ex); } finally { IsFinished = true; } FireTaskProgress(ProgressEventType.Finished, string.Empty, UpdateProgressData.Empty); _requiresRefresh = _support.RequiresRefresh; _support = null; }
public Task SendAsync(ReadOnlyMemory <byte> buffer, Action <IMemoryOwner <byte>, ResponseStatus> callback, ErrorMap errorMap = null) { return(Task.CompletedTask); }
public void SetErrorMap(ErrorMap errorMap) { throw new NotImplementedException(); }
internal static OperationHeader CreateHeader(this ReadOnlySpan <byte> buffer, ErrorMap errorMap, out ErrorCode errorCode) { if (buffer == null || buffer.Length < OperationHeader.Length) { errorCode = null; return(new OperationHeader { Status = ResponseStatus.None }); } int keyLength, framingExtrasLength; var magic = (Magic)buffer[HeaderOffsets.Magic]; if (magic == Magic.AltResponse) { framingExtrasLength = buffer[HeaderOffsets.FramingExtras]; keyLength = buffer[HeaderOffsets.AltKeyLength]; } else { framingExtrasLength = 0; keyLength = ByteConverter.ToInt16(buffer.Slice(HeaderOffsets.KeyLength)); } var statusCode = ByteConverter.ToInt16(buffer.Slice(HeaderOffsets.Status)); var status = GetResponseStatus(statusCode, errorMap, out errorCode); return(new OperationHeader { Magic = (byte)magic, OpCode = buffer[HeaderOffsets.Opcode].ToOpCode(), FramingExtrasLength = framingExtrasLength, KeyLength = keyLength, ExtrasLength = buffer[HeaderOffsets.ExtrasLength], DataType = (DataType)buffer[HeaderOffsets.Datatype], Status = status, BodyLength = ByteConverter.ToInt32(buffer.Slice(HeaderOffsets.Body)), Opaque = ByteConverter.ToUInt32(buffer.Slice(HeaderOffsets.Opaque)), Cas = ByteConverter.ToUInt64(buffer.Slice(HeaderOffsets.Cas)) }); }
public Task SendAsync(ReadOnlyMemory <byte> request, Func <SocketAsyncState, Task> callback, ErrorMap errorMap) { var opaque = Converter.ToUInt32(request.Span.Slice(HeaderOffsets.Opaque)); var state = new AsyncState { Opaque = opaque, Callback = callback, Converter = Converter, EndPoint = (IPEndPoint)EndPoint, ConnectionId = ConnectionId, ErrorMap = errorMap, LocalEndpoint = LocalEndPoint.ToString() }; _statesInFlight.TryAdd(state.Opaque, state); state.Timer = new Timer(o => { AsyncState a = (AsyncState)o; _statesInFlight.TryRemove(a.Opaque, out _); a.Cancel(ResponseStatus.OperationTimeout, new TimeoutException()); }, state, 75000, Timeout.Infinite); lock (Socket) { try { #if NETCOREAPP2_1 var requestSpan = request.Span; while (requestSpan.Length > 0) { var sentBytesCount = Socket.Send(requestSpan, SocketFlags.None); requestSpan = requestSpan.Slice(sentBytesCount); } #else if (!MemoryMarshal.TryGetArray <byte>(request, out var arraySegment)) { // Fallback in case we can't use the more efficient TryGetArray method arraySegment = new ArraySegment <byte>(request.ToArray()); } var sentBytesCount = 0; do { // ReSharper disable once AssignNullToNotNullAttribute sentBytesCount += Socket.Send(arraySegment.Array, arraySegment.Offset + sentBytesCount, arraySegment.Count - sentBytesCount, SocketFlags.None); } while (sentBytesCount < arraySegment.Count); #endif } catch (Exception e) { HandleDisconnect(e); } } return(Task.FromResult(0)); }
public void SetErrorMap(ErrorMap errorMap) { _errorMap = errorMap; }
public override Task SendAsync(byte[] request, Func <SocketAsyncState, Task> callback, ISpan span, ErrorMap errorMap) { var opaque = Converter.ToUInt32(request, HeaderIndexFor.Opaque); var state = new AsyncState { Opaque = opaque, Callback = callback, Converter = Converter, EndPoint = (IPEndPoint)EndPoint, DispatchSpan = span, ConnectionId = ContextId, ErrorMap = errorMap, Timeout = Configuration.SendTimeout, LocalEndpoint = LocalEndPoint.ToString() }; _statesInFlight.TryAdd(state.Opaque, state); state.Timer = new Timer(o => { AsyncState a = (AsyncState)o; _statesInFlight.TryRemove(a.Opaque, out _); a.Cancel(ResponseStatus.OperationTimeout, CreateTimeoutException(opaque)); }, state, Configuration.SendTimeout, Timeout.Infinite); var sentBytesCount = 0; lock (Socket) { try { do { sentBytesCount += Socket.Send(request, sentBytesCount, request.Length - sentBytesCount, SocketFlags.None); } while (sentBytesCount < request.Length); } catch (Exception e) { HandleDisconnect(e); } } return(Task.FromResult(0)); }
public async Task SendAsync(ReadOnlyMemory <byte> request, Func <SocketAsyncState, Task> callback, ErrorMap errorMap) { ExceptionDispatchInfo capturedException = null; SocketAsyncState state = null; try { var opaque = ByteConverter.ToUInt32(request.Span.Slice(HeaderOffsets.Opaque)); state = new SocketAsyncState { Opaque = opaque, EndPoint = (IPEndPoint)EndPoint, ConnectionId = ConnectionId, LocalEndpoint = LocalEndPoint.ToString() }; if (!MemoryMarshal.TryGetArray <byte>(request, out var arraySegment)) { // Fallback in case we can't use the more efficient TryGetArray method arraySegment = new ArraySegment <byte>(request.ToArray()); } // write data to stream await _sslStream.WriteAsync(arraySegment.Array, 0, request.Length).ConfigureAwait(false); // wait for response var received = await _sslStream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length).ConfigureAwait(false); var responseSize = ByteConverter.ToInt32(_receiveBuffer.AsSpan(HeaderOffsets.BodyLength)) + HeaderOffsets.HeaderLength; // create memory slice and copy first segment var response = MemoryPool <byte> .Shared.RentAndSlice(responseSize); _receiveBuffer.AsMemory(0, received).CopyTo(response.Memory); // append any further segments as required while (received < responseSize) { var segmentLength = await _sslStream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length).ConfigureAwait(false); _receiveBuffer.AsMemory(0, segmentLength).CopyTo(response.Memory); received += segmentLength; } // write response to state and complete callback state.SetData(response); await callback(state).ConfigureAwait(false); } catch (Exception e) { IsDead = true; capturedException = ExceptionDispatchInfo.Capture(e); } if (capturedException != null) { var sourceException = capturedException.SourceException; if (state == null) { await callback(new SocketAsyncState { Exception = capturedException.SourceException, Status = (sourceException is SocketException) ? ResponseStatus.TransportFailure : ResponseStatus.ClientFailure }).ConfigureAwait(false); } else { state.Exception = sourceException; await state.Completed(state).ConfigureAwait(false); Log.LogDebug(sourceException, ""); } } }