/// <summary> /// Sends the request. /// </summary> private static int SendRequest(Socket sock, Action <BinaryHeapStream> writeAction) { using (var stream = new BinaryHeapStream(128)) { stream.WriteInt(0); // Reserve message size. writeAction(stream); stream.WriteInt(0, stream.Position - 4); // Write message size. return(sock.Send(stream.GetArray(), stream.Position, SocketFlags.None)); } }
/// <summary> /// Writes the message to a byte array. /// </summary> private RequestMessage WriteMessage(Action <IBinaryStream> writeAction, ClientOp opId) { var requestId = Interlocked.Increment(ref _requestId); var stream = new BinaryHeapStream(256); stream.WriteInt(0); // Reserve message size. stream.WriteShort((short)opId); stream.WriteLong(requestId); writeAction(stream); stream.WriteInt(0, stream.Position - 4); // Write message size. return(new RequestMessage(requestId, stream.GetArray(), stream.Position)); }
/// <summary> /// Lazy fields initialization routine. /// </summary> private void InitializeFields() { if (_fields != null) { return; } var stream = new BinaryHeapStream(_data); var hdr = BinaryObjectHeader.Read(stream, _offset); _fields = hdr.ReadSchemaAsDictionary(stream, _offset) ?? EmptyFields; }
/// <summary> /// Sends the request. /// </summary> private static void SendRequest(Stream sock, Action <BinaryHeapStream> writeAction) { using (var stream = new BinaryHeapStream(128)) { stream.WriteInt(0); // Reserve message size. writeAction(stream); stream.WriteInt(0, stream.Position - 4); // Write message size. sock.Write(stream.GetArray(), 0, stream.Position); } }
/// <summary> /// Create empty binary object from descriptor. /// </summary> /// <param name="desc">Descriptor.</param> /// <returns>Empty binary object.</returns> private BinaryObject BinaryFromDescriptor(IBinaryTypeDescriptor desc) { var len = BinaryObjectHeader.Size; var hdr = new BinaryObjectHeader(desc.TypeId, 0, len, 0, len, desc.UserType ? BinaryObjectHeader.Flag.UserType : BinaryObjectHeader.Flag.None); var stream = new BinaryHeapStream(len); BinaryObjectHeader.Write(hdr, stream, 0); return(new BinaryObject(_marsh, stream.InternalArray, 0, hdr)); }
/// <summary> /// Returns a hash code for this instance. /// </summary> /// <param name="obj">The object.</param> /// <returns> /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// </returns> public static int GetHashCode(IBinaryObject obj) { if (obj == null) return 0; var binObj = GetBinaryObject(obj); var arg = new KeyValuePair<int, int>(GetDataStart(binObj), GetDataLength(binObj)); using (var stream = new BinaryHeapStream(binObj.Data)) { return stream.Apply(HashCodeProcessor, arg); } }
/// <summary> /// Receives the message. /// </summary> private static byte[] ReceiveMessage(Stream sock) { var buf = new byte[4]; sock.Read(buf, 0, 4); using (var stream = new BinaryHeapStream(buf)) { var size = stream.ReadInt(); buf = new byte[size]; sock.Read(buf, 0, size); return(buf); } }
public void TestArrayComparer() { var cmp = (IBinaryEqualityComparer) new BinaryArrayEqualityComparer(); var ms = new BinaryHeapStream(10); Assert.AreEqual(1, cmp.GetHashCode(ms, 0, 0, null, 0, null, null)); ms.WriteByte(1); Assert.AreEqual(31 + 1, cmp.GetHashCode(ms, 0, 1, null, 0, null, null)); ms.WriteByte(3); Assert.AreEqual((31 + 1) * 31 + 3, cmp.GetHashCode(ms, 0, 2, null, 0, null, null)); }
public void TestCacheGet() { var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration()) { SqlConnectorConfiguration = new SqlConnectorConfiguration() }; using (var ignite = Ignition.Start(cfg)) { var marsh = ((Ignite)ignite).Marshaller; // Create cache. var cacheCfg = new CacheConfiguration("foo", new QueryEntity(typeof(int), typeof(string))); var cache = ignite.CreateCache <int, string>(cacheCfg); cache[1] = "bar"; // Connect socket. var sock = GetSocket(SqlConnectorConfiguration.DefaultPort); Assert.IsTrue(sock.Connected); DoHandshake(sock); // Cache get. SendRequest(sock, stream => { stream.WriteShort(1); // OP_GET stream.WriteLong(1); // Request id. var cacheId = BinaryUtils.GetStringHashCode(cache.Name); stream.WriteInt(cacheId); stream.WriteByte(0); // Flags (withSkipStore, etc) var writer = marsh.StartMarshal(stream); writer.WriteObject(1); // Key }); var msg = ReceiveMessage(sock); using (var stream = new BinaryHeapStream(msg)) { var reader = marsh.StartUnmarshal(stream); var requestId = reader.ReadLong(); Assert.AreEqual(1, requestId); var res = reader.ReadObject <string>(); Assert.AreEqual(cache[1], res); } } }
/// <summary> /// Handles the response. /// </summary> private void HandleResponse(byte[] response) { var stream = new BinaryHeapStream(response); var requestId = stream.ReadLong(); Request req; if (!_requests.TryRemove(requestId, out req)) { // Response with unknown id. throw new IgniteClientException("Invalid thin client response id: " + requestId); } req.CompletionSource.TrySetResult(stream); }
/// <summary> /// Serializes and deserializes back an instance. /// </summary> private static IgniteSessionStateStoreData SerializeDeserialize(IgniteSessionStateStoreData data) { var marsh = BinaryUtils.Marshaller; using (var stream = new BinaryHeapStream(128)) { var writer = marsh.StartMarshal(stream); data.WriteBinary(writer.GetRawWriter(), false); stream.Seek(0, SeekOrigin.Begin); return(new IgniteSessionStateStoreData(marsh.StartUnmarshal(stream))); } }
/// <summary> /// Writes the message to a byte array. /// </summary> private static byte[] WriteMessage(Action <IBinaryStream> writeAction, int bufSize, out int messageLen) { using (var stream = new BinaryHeapStream(bufSize)) { stream.WriteInt(0); // Reserve message size. writeAction(stream); stream.WriteInt(0, stream.Position - 4); // Write message size. messageLen = stream.Position; return(stream.GetArray()); } }
/// <summary> /// Returns a hash code for this instance. /// </summary> /// <param name="obj">The object.</param> /// <returns> /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// </returns> public int GetHashCode(IBinaryObject obj) { if (obj == null) { return(0); } var binObj = GetBinaryObject(obj); var arg = new KeyValuePair <int, int>(GetDataStart(binObj), GetDataLength(binObj)); using (var stream = new BinaryHeapStream(binObj.Data)) { return(stream.Apply(this, arg)); } }
/// <summary> /// Serializes and deserializes back an instance. /// </summary> private static IgniteSessionStateItemCollection SerializeDeserialize(IgniteSessionStateItemCollection data, bool changesOnly = false) { var marsh = BinaryUtils.Marshaller; using (var stream = new BinaryHeapStream(128)) { var writer = marsh.StartMarshal(stream); data.WriteBinary(writer.GetRawWriter(), changesOnly); stream.Seek(0, SeekOrigin.Begin); return(new IgniteSessionStateItemCollection(marsh.StartUnmarshal(stream))); } }
/// <summary> /// Lazy fields initialization routine. /// </summary> private void InitializeFields(IBinaryTypeDescriptor desc = null) { if (_fields != null) { return; } desc = desc ?? _marsh.GetDescriptor(true, _header.TypeId); using (var stream = new BinaryHeapStream(_data)) { var hdr = BinaryObjectHeader.Read(stream, _offset); _fields = BinaryObjectSchemaSerializer.ReadSchema(stream, _offset, hdr, desc.Schema, _marsh) .ToDictionary() ?? EmptyFields; } }
/// <summary> /// Performs client protocol handshake. /// </summary> private void Handshake(ClientProtocolVersion version) { // Send request. int messageLen; var buf = WriteMessage(stream => { // Handshake. stream.WriteByte(OpHandshake); // Protocol version. stream.WriteShort(version.Major); stream.WriteShort(version.Minor); stream.WriteShort(version.Maintenance); // Client type: platform. stream.WriteByte(ClientType); }, 12, out messageLen); Debug.Assert(messageLen == 12); var sent = _socket.Send(buf, messageLen, SocketFlags.None); Debug.Assert(sent == messageLen); // Decode response. var res = ReceiveMessage(); using (var stream = new BinaryHeapStream(res)) { var success = stream.ReadBool(); if (success) { return; } var serverVersion = new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort()); var errMsg = BinaryUtils.Marshaller.Unmarshal <string>(stream); throw new IgniteClientException(string.Format( "Client handshake failed: '{0}'. Client version: {1}. Server version: {2}", errMsg, version, serverVersion)); } }
/// <summary> /// Process child builder. /// </summary> /// <param name="outStream">Output stream.</param> /// <param name="builder">Builder.</param> internal void ProcessBuilder(IBinaryStream outStream, BinaryObjectBuilder builder) { BinaryHeapStream inStream = new BinaryHeapStream(builder._obj.Data); inStream.Seek(builder._obj.Offset, SeekOrigin.Begin); // Builder parent context might be null only in one case: if we never met this group of // builders before. In this case we set context to their parent and track it. Context // cleanup will be performed at the very end of build process. if (builder._parent._ctx == null || builder._parent._ctx.Closed) { builder._parent._ctx = new Context(_parent._ctx); } builder.Mutate(inStream, outStream as BinaryHeapStream, builder._desc, builder._hashCode, builder._vals); }
public void TestCacheGet() { var ignite = Ignition.GetIgnite(); var marsh = ((Ignite)ignite).Marshaller; // Create cache. var cache = GetCache <string>(); cache[1] = "bar"; // Connect socket. var sock = GetSocket(); // Cache get. SendRequest(sock, stream => { stream.WriteShort(1000); // OP_GET stream.WriteLong(1); // Request id. var cacheId = BinaryUtils.GetStringHashCodeLowerCase(cache.Name); stream.WriteInt(cacheId); stream.WriteByte(0); // Flags (withSkipStore, etc) var writer = marsh.StartMarshal(stream); writer.WriteObject(1); // Key }); var msg = ReceiveMessage(sock); using (var stream = new BinaryHeapStream(msg)) { var reader = marsh.StartUnmarshal(stream); var requestId = reader.ReadLong(); Assert.AreEqual(1, requestId); var status = reader.ReadInt(); Assert.AreEqual(0, status); // Success. var res = reader.ReadObject <string>(); Assert.AreEqual(cache[1], res); } }
public void TestCustomConfigurationPropagatesToServer() { var cfg1 = new AtomicClientConfiguration { AtomicSequenceReserveSize = 32, Backups = 2, CacheMode = CacheMode.Partitioned, GroupName = "atomics-partitioned" }; var cfg2 = new AtomicClientConfiguration { AtomicSequenceReserveSize = 33, Backups = 3, CacheMode = CacheMode.Replicated, GroupName = "atomics-replicated" }; var name = TestUtils.TestName; var atomicLong1 = Client.GetAtomicLong(name, cfg1, 1, true); var atomicLong2 = Client.GetAtomicLong(name, cfg2, 2, true); var atomicLong3 = Client.GetAtomicLong(name, 3, true); var cacheConfigBytes = GetIgnite().GetCompute().ExecuteJavaTask <byte[]>( "org.apache.ignite.platform.PlatformGetInternalCachesTask", null); Assert.IsNotNull(cacheConfigBytes); var stream = new BinaryHeapStream(cacheConfigBytes); var reader = new BinaryReader(BinaryUtils.Marshaller, stream, BinaryMode.Deserialize, null); var caches = Enumerable.Range(0, reader.ReadInt()) .Select(_ => new CacheConfiguration(reader)) .ToDictionary(c => c.Name); Assert.AreEqual(2, caches["ignite-sys-atomic-cache@atomics-partitioned"].Backups); Assert.AreEqual(int.MaxValue, caches["ignite-sys-atomic-cache@atomics-replicated"].Backups); Assert.AreEqual(1, caches["ignite-sys-atomic-cache@default-ds-group"].Backups); Assert.AreEqual(1, atomicLong1.Read()); Assert.AreEqual(2, atomicLong2.Read()); Assert.AreEqual(3, atomicLong3.Read()); }
/// <summary> /// Decodes the response that we got from <see cref="HandleResponse"/>. /// </summary> private static T DecodeResponse <T>(BinaryHeapStream stream, Func <IBinaryStream, T> readFunc, Func <ClientStatusCode, string, T> errorFunc) { var statusCode = (ClientStatusCode)stream.ReadInt(); if (statusCode == ClientStatusCode.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, statusCode); }
/// <summary> /// Writes the message to a byte array. /// </summary> private RequestMessage WriteMessage(Action <IBinaryStream> writeAction, ClientOp opId) { ValidateOp(opId); var requestId = Interlocked.Increment(ref _requestId); // Potential perf improvements: // * ArrayPool<T> // * Write to socket stream directly (not trivial because of unknown size) var stream = new BinaryHeapStream(256); stream.WriteInt(0); // Reserve message size. stream.WriteShort((short)opId); stream.WriteLong(requestId); writeAction(stream); stream.WriteInt(0, stream.Position - 4); // Write message size. return(new RequestMessage(requestId, stream.GetArray(), stream.Position)); }
/// <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); }
private IBinaryRawReader SetUpRawBinaryReader(byte[] hash) { var marsh = BinaryUtils.Marshaller; using (var stream = new BinaryHeapStream(128)) { var writer = marsh.StartMarshal(stream); writer.WriteByte(_defaultVersion.Major); writer.WriteByte(_defaultVersion.Minor); writer.WriteByte(_defaultVersion.Maintenance); writer.WriteString(_defaultVersion.Stage); writer.WriteLong(BinaryUtils.DateTimeToJavaTicks(_defaultVersion.ReleaseDate)); writer.WriteByteArray(hash); stream.Seek(0, SeekOrigin.Begin); return(marsh.StartUnmarshal(stream)); } }
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> /// Create empty binary object from descriptor. /// </summary> /// <param name="desc">Descriptor.</param> /// <returns>Empty binary object.</returns> private BinaryObject BinaryFromDescriptor(IBinaryTypeDescriptor desc) { const int len = BinaryObjectHeader.Size; var flags = desc.UserType ? BinaryObjectHeader.Flag.UserType : BinaryObjectHeader.Flag.None; if (_marsh.CompactFooter && desc.UserType) { flags |= BinaryObjectHeader.Flag.CompactFooter; } var hdr = new BinaryObjectHeader(desc.TypeId, 0, len, 0, len, flags); using (var stream = new BinaryHeapStream(len)) { BinaryObjectHeader.Write(hdr, stream, 0); return(new BinaryObject(_marsh, stream.InternalArray, 0, hdr)); } }
/// <summary> /// Handles the notification message, if present in the given stream. /// </summary> private bool HandleNotification(long requestId, BinaryHeapStream stream) { if (ServerVersion < Ver160) { return(false); } var flags = (ClientFlags)stream.ReadShort(); stream.Seek(-2, SeekOrigin.Current); if ((flags & ClientFlags.Notification) != ClientFlags.Notification) { return(false); } _notificationListeners.GetOrAdd(requestId, _ => new ClientNotificationHandler(_logger)) .Handle(stream, null); return(true); }
/// <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> /// Internal deserialization routine. /// </summary> /// <param name="mode">The mode.</param> /// <returns> /// Deserialized object. /// </returns> private T Deserialize <T>(BinaryMode mode) { if (_deserialized == null) { IBinaryStream stream = new BinaryHeapStream(_data); stream.Seek(_offset, SeekOrigin.Begin); T res = _marsh.Unmarshal <T>(stream, mode); IBinaryTypeDescriptor desc = _marsh.GetDescriptor(true, _header.TypeId); if (!desc.KeepDeserialized) { return(res); } _deserialized = res; } return((T)_deserialized); }
/// <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); }