Пример #1
0
        /// <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);
            }
        }
Пример #2
0
        /// <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));
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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());
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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);
            }
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
                }
            }
        }