/// <summary> /// Handles the response. /// </summary> private void HandleResponse(byte[] response) { var stream = new BinaryHeapStream(response); var requestId = stream.ReadLong(); if (HandleNotification(requestId, stream)) { return; } Request req; if (!_requests.TryRemove(requestId, out req)) { if (_exception != null) { return; } // Response with unknown id. throw new IgniteClientException("Invalid thin client response id: " + requestId); } if (req != null) { req.CompletionSource.TrySetResult(stream); } }
/// <summary> /// Performs a send-receive operation. /// </summary> public T DoOutInOp <T>(ClientOp opId, Action <IBinaryStream> writeAction, Func <IBinaryStream, T> readFunc) { var requestId = Interlocked.Increment(ref _requestId); var resBytes = SendReceive(_socket, stream => { stream.WriteShort((short)opId); stream.WriteLong(requestId); if (writeAction != null) { writeAction(stream); } }); using (var stream = new BinaryHeapStream(resBytes)) { var resRequestId = stream.ReadLong(); Debug.Assert(requestId == resRequestId); if (readFunc != null) { return(readFunc(stream)); } } return(default(T)); }
/// <summary> /// Decodes the response that we got from <see cref="HandleResponse"/>. /// </summary> private T DecodeResponse <T>(BinaryHeapStream stream, Func <ClientResponseContext, T> readFunc, Func <ClientStatusCode, string, T> errorFunc) { ClientStatusCode statusCode; if (ServerVersion >= Ver140) { var flags = (ClientFlags)stream.ReadShort(); if ((flags & ClientFlags.AffinityTopologyChanged) == ClientFlags.AffinityTopologyChanged) { var topVer = new AffinityTopologyVersion(stream.ReadLong(), stream.ReadInt()); if (_topVerCallback != null) { _topVerCallback(topVer); } } statusCode = (flags & ClientFlags.Error) == ClientFlags.Error ? (ClientStatusCode)stream.ReadInt() : ClientStatusCode.Success; } else { statusCode = (ClientStatusCode)stream.ReadInt(); } if (statusCode == ClientStatusCode.Success) { return(readFunc != null ? readFunc(new ClientResponseContext(stream, this)) : default(T)); } var msg = BinaryUtils.Marshaller.StartUnmarshal(stream).ReadString(); if (errorFunc != null) { return(errorFunc(statusCode, msg)); } throw new IgniteClientException(msg, null, statusCode); }
public void TestCustomPosition() { var stream = new BinaryHeapStream(16); stream.WriteLong(54); var marsh = new Marshaller(new BinaryConfiguration()); var writer = new BinaryWriter(marsh, stream); writer.WriteChar('x'); stream.Seek(0, SeekOrigin.Begin); Assert.AreEqual(54, stream.ReadLong()); var reader = new BinaryReader(marsh, stream, BinaryMode.Deserialize, null); Assert.AreEqual('x', reader.ReadChar()); }
/// <summary> /// Sends the request synchronously. /// </summary> private BinaryHeapStream SendRequest(ref RequestMessage reqMsg) { // Do not enter lock when disposed. CheckException(); // If there are no pending async requests, we can execute this operation synchronously, // which is more efficient. var lockTaken = false; try { Monitor.TryEnter(_sendRequestSyncRoot, 0, ref lockTaken); if (lockTaken) { CheckException(); if (_requests.IsEmpty) { SocketWrite(reqMsg.Buffer, reqMsg.Length); var respMsg = ReceiveMessage(); var response = new BinaryHeapStream(respMsg); var responseId = response.ReadLong(); Debug.Assert(responseId == reqMsg.Id); return(response); } } } finally { if (lockTaken) { Monitor.Exit(_sendRequestSyncRoot); } } // Fallback to async mechanism. return(SendRequestAsync(ref reqMsg).Result); }
/// <summary> /// Performs a send-receive operation. /// </summary> public T DoOutInOp <T>(ClientOp opId, Action <IBinaryStream> writeAction, Func <IBinaryStream, T> readFunc, Func <ClientStatus, string, T> errorFunc = null) { var requestId = Interlocked.Increment(ref _requestId); var resBytes = SendReceive(_socket, stream => { stream.WriteShort((short)opId); stream.WriteLong(requestId); if (writeAction != null) { writeAction(stream); } }); using (var stream = new BinaryHeapStream(resBytes)) { var resRequestId = stream.ReadLong(); Debug.Assert(requestId == resRequestId); var statusCode = (ClientStatus)stream.ReadInt(); if (statusCode == ClientStatus.Success) { return(readFunc != null?readFunc(stream) : default(T)); } var msg = BinaryUtils.Marshaller.StartUnmarshal(stream).ReadString(); if (errorFunc != null) { return(errorFunc(statusCode, msg)); } throw new IgniteClientException(msg, null, (int)statusCode); } }
/// <summary> /// Sends the request synchronously. /// </summary> private BinaryHeapStream SendRequest(ref RequestMessage reqMsg) { // Do not enter lock when disposed. CheckException(); // If there are no pending async requests, we can execute this operation synchronously, // which is more efficient. if (_sendRequestLock.TryEnterWriteLock(0)) { try { CheckException(); if (_requests.IsEmpty) { _socket.Send(reqMsg.Buffer, 0, reqMsg.Length, SocketFlags.None); var respMsg = ReceiveMessage(); var response = new BinaryHeapStream(respMsg); var responseId = response.ReadLong(); Debug.Assert(responseId == reqMsg.Id); return(response); } } finally { if (_sendRequestLock.IsWriteLockHeld) { _sendRequestLock.ExitWriteLock(); } } } // Fallback to async mechanism. return(SendRequestAsync(ref reqMsg).Result); }
/// <summary> /// Sends the request synchronously. /// </summary> private BinaryHeapStream SendRequest(ref RequestMessage reqMsg) { // Do not enter lock when disposed. CheckException(); // If there are no pending async requests, we can execute this operation synchronously, // which is more efficient. if (IsAsyncMode) { return(null); } var sendLockTaken = false; var receiveLockTaken = false; try { Monitor.TryEnter(_sendRequestSyncRoot, 0, ref sendLockTaken); if (!sendLockTaken) { return(null); } Monitor.TryEnter(_receiveMessageSyncRoot, 0, ref receiveLockTaken); if (!receiveLockTaken) { return(null); } CheckException(); if (IsAsyncMode) { return(null); } SocketWrite(reqMsg.Buffer, reqMsg.Length); // Sync operations rely on stream timeout. if (!_isReadTimeoutEnabled) { _stream.ReadTimeout = _stream.WriteTimeout; _isReadTimeoutEnabled = true; } var respMsg = ReceiveMessage(); var response = new BinaryHeapStream(respMsg); var responseId = response.ReadLong(); Debug.Assert(responseId == reqMsg.Id); return(response); } finally { if (sendLockTaken) { Monitor.Exit(_sendRequestSyncRoot); } if (receiveLockTaken) { Monitor.Exit(_receiveMessageSyncRoot); } } }