/** * <summary> * Converts protocol object into object.</summary> * * <param name="val">Protocol message object to convert into value.</param> * <returns>Recovered object.</returns> */ public static Object WrapObject(ObjectWrapper val) { byte[] bin = val.Binary.ToByteArray(); // Primitives. switch (val.Type) { case ObjectWrapperType.NONE: return(null); case ObjectWrapperType.BOOL: Dbg.Assert(bin.Length == 1, "bin.Length == 1"); return(bin[0] != 0); case ObjectWrapperType.BYTE: Dbg.Assert(bin.Length == 1, "bin.Length == 1"); return(bin[0]); case ObjectWrapperType.SHORT: Dbg.Assert(bin.Length == 2, "bin.Length == 2"); return(U.BytesToInt16(bin, 0)); case ObjectWrapperType.INT32: Dbg.Assert(bin.Length == 4, "bin.Length == 4"); return(U.BytesToInt32(bin, 0)); case ObjectWrapperType.INT64: Dbg.Assert(bin.Length == 8, "bin.Length == 8"); return(U.BytesToInt64(bin, 0)); case ObjectWrapperType.FLOAT: Dbg.Assert(bin.Length == 4, "bin.Length == 4"); return(U.BytesToSingle(bin, 0)); case ObjectWrapperType.DOUBLE: Dbg.Assert(bin.Length == 8, "bin.Length == 8"); return(U.BytesToDouble(bin, 0)); case ObjectWrapperType.BYTES: return(bin); case ObjectWrapperType.UUID: return(WrapGuid(val.Binary)); case ObjectWrapperType.STRING: return(val.Binary.ToStringUtf8()); case ObjectWrapperType.COLLECTION: return(WrapCollection(Collection.ParseFrom(bin))); case ObjectWrapperType.MAP: return(WrapMap(Map.ParseFrom(bin))); case ObjectWrapperType.AUTH_REQUEST: return(WrapAuthRequest(ProtoRequest.ParseFrom(bin))); case ObjectWrapperType.CACHE_REQUEST: return(WrapCacheRequest(ProtoRequest.ParseFrom(bin))); case ObjectWrapperType.TASK_REQUEST: return(WrapTaskRequest(ProtoRequest.ParseFrom(bin))); case ObjectWrapperType.LOG_REQUEST: return(WrapLogRequest(ProtoRequest.ParseFrom(bin))); case ObjectWrapperType.TOPOLOGY_REQUEST: return(WrapTopologyRequest(ProtoRequest.ParseFrom(bin))); case ObjectWrapperType.RESPONSE: return(WrapResponse(ProtoResponse.ParseFrom(bin))); case ObjectWrapperType.NODE_BEAN: return(WrapNode(ProtoNodeBean.ParseFrom(bin))); case ObjectWrapperType.TASK_BEAN: return(WrapTaskResult(ProtoTaskBean.ParseFrom(bin))); default: throw new ArgumentException("Failed to deserialize object (object deserialization" + " of given type is not supported): " + val.Type); } }
/** <summary>Reader thread.</summary> */ private void readPackets() { try { bool running = true; while (running) { // Note that only this thread removes futures from map. // So if we see closed condition, it is safe to check map size since no more futures // will be added to the map. if (closed) { // Exit if either all requests processed or we do not wait for completion. if (!waitCompletion) { break; } lock (pendingReqs) { if (pendingReqs.Count == 0) { break; } } } // Header. int symbol; try { symbol = readByte(); } catch (TimeoutException) { checkPing(); continue; } // Connection closed. if (symbol == -1) { Dbg.WriteLine("Connection closed by remote host " + "[srvAddr=" + ServerAddress + ", symbol=" + symbol + "]"); break; } // Check for correct header. if ((byte)symbol != (byte)0x90) { Dbg.WriteLine("Failed to parse incoming message (unexpected header received, will close) " + "[srvAddr=" + ServerAddress + ", symbol=" + symbol + "]"); break; } // Packet. MemoryStream buf = new MemoryStream(); int len = 0; while (true) { try { symbol = readByte(); } catch (TimeoutException) { checkPing(); continue; } if (symbol == -1) { running = false; break; } byte b = (byte)symbol; buf.WriteByte(b); if (len == 0) { if (buf.Length == 4) { len = U.BytesToInt32(buf.ToArray(), 0); // Reset buffer. buf.SetLength(0); if (len == 0) { // Ping received. lastPingRcvTime = U.Now; break; } } } else { if (buf.Length == len) { if (len < 40) { Dbg.WriteLine("Invalid packet received [len=" + len + ", buf=" + buf + "]"); break; } buf.Position = 0; // Rewind buffer. byte[] head = new byte[40]; byte[] packet = new byte[len - head.Length]; buf.Read(head, 0, head.Length); buf.Read(packet, 0, packet.Length); GridClientResponse msg = marshaller.Unmarshal <GridClientResponse>(packet); msg.RequestId = U.BytesToInt64(head, 0); msg.ClientId = U.BytesToGuid(head, 8); msg.DestNodeId = U.BytesToGuid(head, 24); // Reset buffer. buf.SetLength(0); len = 0; lastPacketRcvTime = U.Now; handleResponse(msg); break; } } } } } catch (IOException e) { if (!closed) { Dbg.WriteLine("Failed to read data from remote host (will close connection)" + " [addr=" + ServerAddress + ", e=" + e.Message + "]"); } } catch (Exception e) { Dbg.WriteLine("Unexpected throwable in connection reader thread (will close connection)" + " [addr={0}, e={1}]", ServerAddress, e); } finally { U.Async(() => Close(false)); } }
/** <summary>Reader thread.</summary> */ private void readPackets() { try { bool running = true; byte[] lenByte = new byte[4]; byte[] head = new byte[40]; while (running) { // Note that only this thread removes futures from map. // So if we see closed condition, it is safe to check map size since no more futures // will be added to the map. if (closed) { // Exit if either all requests processed or we do not wait for completion. if (!waitCompletion) { break; } if (pendingReqs.Count == 0) { break; } } // Header. int symbol; try { if (lastReadTimedOut) { lastReadTimedOut = false; if (isSslStream) { // Recover SSL stream state after socket exception. skipSslDataRecordHeader(); } } symbol = inStream.ReadByte(); } catch (Exception e) { if (e.InnerException is SocketException) { e = e.InnerException; } var sockEx = e as SocketException; if (sockEx != null && sockEx.ErrorCode == 10060) { checkPing(); lastReadTimedOut = true; continue; } // All other exceptions are interpreted as stream ends. throw; } // Connection closed. if (symbol == -1) { Dbg.WriteLine("Connection closed by remote host " + "[srvAddr=" + ServerAddress + ", symbol=" + symbol + "]"); break; } // Check for correct header. if ((byte)symbol != (byte)0x90) { Dbg.WriteLine("Failed to parse incoming message (unexpected header received, will close) " + "[srvAddr=" + ServerAddress + ", symbol=" + symbol + "]"); break; } U.ReadFully(inStream, lenByte, 0, 4); int len = U.BytesToInt32(lenByte, 0); if (len == 0) { // Ping received. lastPingRcvTime = U.Now; continue; } if (len < 40) { Dbg.WriteLine("Invalid packet received [len=" + len + "]"); break; } U.ReadFully(inStream, head, 0, 40); long reqId = U.BytesToInt64(head, 0); Guid clientId = U.BytesToGuid(head, 8); Guid destNodeId = U.BytesToGuid(head, 24); byte[] msgBytes = new byte[len - 40]; U.ReadFully(inStream, msgBytes, 0, msgBytes.Length); GridClientResponse msg = marshaller.Unmarshal <GridClientResponse>(msgBytes); msg.RequestId = reqId; msg.ClientId = clientId; msg.DestNodeId = destNodeId; lastPacketRcvTime = U.Now; handleResponse(msg); } } catch (IOException e) { if (!closed) { Dbg.WriteLine("Failed to read data from remote host (will close connection)" + " [addr=" + ServerAddress + ", e=" + e.Message + "]"); } } catch (Exception e) { Dbg.WriteLine("Unexpected throwable in connection reader thread (will close connection)" + " [addr={0}, e={1}]", ServerAddress, e); } finally { U.Async(() => Close(false)); } }