public Packet QueuePacket(RequestHeader h, ReplyHeader r, IRecord request, IRecord response, string clientPath, string serverPath, ZooKeeper.WatchRegistration watchRegistration) { lock (outgoingQueueLock) { //lock here for XID? if (h.Type != (int)OpCode.Ping && h.Type != (int)OpCode.Auth) { h.Xid = Xid; } Packet p = new Packet(h, r, request, response, null, watchRegistration, clientPath, serverPath); p.clientPath = clientPath; p.serverPath = serverPath; if (!zooKeeper.State.IsAlive()) ConLossPacket(p); else { outgoingQueue.AddLast(p); Monitor.PulseAll(outgoingQueueLock); } return p; } }
private void FinishPacket(Packet p) { if (p.watchRegistration != null) { p.watchRegistration.Register(p.replyHeader.Err); } p.Finished = true; conn.consumer.QueuePacket(p); }
private void PrimeConnection(TcpClient client) { LOG.Info(string.Format("Socket connection established to {0}, initiating session", client.Client.RemoteEndPoint)); ConnectRequest conReq = new ConnectRequest(0, lastZxid, Convert.ToInt32(conn.SessionTimeout.TotalMilliseconds), conn.SessionId, conn.SessionPassword); byte[] buffer; using (MemoryStream ms = new MemoryStream()) using (EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Big, ms, Encoding.UTF8)) { BinaryOutputArchive boa = BinaryOutputArchive.getArchive(writer); boa.WriteInt(-1, "len"); conReq.Serialize(boa, "connect"); ms.Position = 0; writer.Write(ms.ToArray().Length - 4); buffer = ms.ToArray(); } lock (outgoingQueueLock) { if (!ClientConnection.disableAutoWatchReset && (!zooKeeper.DataWatches.IsEmpty() || !zooKeeper.ExistWatches.IsEmpty() || !zooKeeper.ChildWatches.IsEmpty())) { var sw = new SetWatches(lastZxid, zooKeeper.DataWatches, zooKeeper.ExistWatches, zooKeeper.ChildWatches); var h = new RequestHeader(); h.Type = (int)OpCode.SetWatches; h.Xid = -8; Packet packet = new Packet(h, new ReplyHeader(), sw, null, null, null, null, null); outgoingQueue.AddFirst(packet); } foreach (ClientConnection.AuthData id in conn.authInfo) { outgoingQueue.AddFirst(new Packet(new RequestHeader(-4, (int)OpCode.Auth), null, new AuthPacket(0, id.scheme, id.data), null, null, null, null, null)); } outgoingQueue.AddFirst((new Packet(null, null, null, null, buffer, null, null, null))); } lock (this) { EnableWrite(); } if (LOG.IsDebugEnabled) { LOG.Debug("Session establishment request sent on " + client.Client.RemoteEndPoint); } }
public void QueuePacket(Packet p) { }
private void ConLossPacket(Packet p) { if (p.replyHeader == null) return; string state = zooKeeper.State.State; if (state == ZooKeeper.States.AUTH_FAILED.State) p.replyHeader.Err = (int)KeeperException.Code.AUTHFAILED; else if (state == ZooKeeper.States.CLOSED.State) p.replyHeader.Err = (int)KeeperException.Code.SESSIONEXPIRED; else p.replyHeader.Err = (int)KeeperException.Code.CONNECTIONLOSS; FinishPacket(p); }
public Packet QueuePacket(RequestHeader h, ReplyHeader r, IRecord request, IRecord response, string clientPath, string serverPath, ZooKeeper.WatchRegistration watchRegistration) { if (h.Type != (int)OpCode.Ping && h.Type != (int)OpCode.Auth) h.Xid = Xid; Packet p = new Packet(h, r, request, response, null, watchRegistration, clientPath, serverPath); if (!zooKeeper.State.IsAlive() || closing || Interlocked.CompareExchange(ref isDisposed, 0, 0) == 1) { if(LOG.IsDebugEnabled) LOG.DebugFormat("Connection closing. Sending ConLossPacket. IsAlive: {0}, closing: {1}", zooKeeper.State.IsAlive(), closing); ConLossPacket(p); } else { if (h.Type == (int)OpCode.CloseSession) closing = true; // enqueue the packet when zookeeper is connected addPacketLast(p); } return p; }
public void QueuePacket(Packet packet) { AppendToQueue(packet); }
/// <summary> /// send packet to server /// there's posibility when server closed the socket and client try to send some packet, when this happen it will throw exception /// the exception is either IOException, NullReferenceException and/or ObjectDisposedException /// so it is mandatory to catch these excepetions /// </summary> /// <param name="packet">The packet to send</param> private void DoSend(Packet packet) { if (packet.header != null && packet.header.Type != (int)OpCode.Ping && packet.header.Type != (int)OpCode.Auth) { pendingQueue.Enqueue(packet); } client.GetStream().Write(packet.data, 0, packet.data.Length); sentCount++; }
private static void FinishPacket(Packet p) { if (p.watchRegistration != null) p.watchRegistration.Register(p.replyHeader.Err); p.Finished = true; }
private void PrimeConnection() { LOG.InfoFormat("Socket connection established to {0}, initiating session", client.Client.RemoteEndPoint); ConnectRequest conReq = new ConnectRequest(0, lastZxid, Convert.ToInt32(conn.SessionTimeout.TotalMilliseconds), conn.SessionId, conn.SessionPassword); lock (outgoingQueue) { if (!ClientConnection.DisableAutoWatchReset && (!zooKeeper.DataWatches.IsEmpty() || !zooKeeper.ExistWatches.IsEmpty() || !zooKeeper.ChildWatches.IsEmpty())) { var sw = new SetWatches(lastZxid, zooKeeper.DataWatches, zooKeeper.ExistWatches, zooKeeper.ChildWatches); var h = new RequestHeader(); h.Type = (int)OpCode.SetWatches; h.Xid = -8; Packet packet = new Packet(h, new ReplyHeader(), sw, null, null, null, null, null); //outgoingQueue.AddFirst(packet); addPacketFirst(packet); } foreach (ClientConnection.AuthData id in conn.authInfo) addPacketFirst( new Packet(new RequestHeader(-4, (int) OpCode.Auth), null, new AuthPacket(0, id.Scheme, id.GetData()), null, null, null, null, null)); addPacketFirst(new Packet(null, null, conReq, null, null, null, null, null)); } packetAre.Set(); if (LOG.IsDebugEnabled) LOG.DebugFormat("Session establishment request sent on {0}",client.Client.RemoteEndPoint); }
private void addPacketLast(Packet p) { lock (outgoingQueue) { outgoingQueue.AddLast(p); } packetAre.Set(); }
private void addPacketFirst(Packet p) { outgoingQueue.AddFirst(p); }
private void SendRequests() { DateTime now = DateTime.UtcNow; DateTime lastSend = now; Packet packet = null; while (zooKeeper.State.IsAlive()) { try { now = DateTime.UtcNow; if ((client == null || client.Client == null) || (!client.Connected || zooKeeper.State == ZooKeeper.States.NOT_CONNECTED)) { // don't re-establish connection if we are closing if (conn.IsClosed || closing) { break; } StartConnect(); lastSend = now; } TimeSpan idleSend = now - lastSend; if (zooKeeper.State == ZooKeeper.States.CONNECTED) { TimeSpan timeToNextPing = new TimeSpan(0, 0, 0, 0, Convert.ToInt32(conn.readTimeout.TotalMilliseconds / 2 - idleSend.TotalMilliseconds)); if (timeToNextPing <= TimeSpan.Zero) { SendPing(); } } // Everything below and until we get back to the select is // non blocking, so time is effectively a constant. That is // Why we just have to do this once, here packet = null; lock (outgoingQueue) { if (!outgoingQueue.IsEmpty()) { packet = outgoingQueue.First(); outgoingQueue.RemoveFirst(); } } if (packet != null) { // We have something to send so it's the same // as if we do the send now. DoSend(packet); lastSend = DateTime.UtcNow; packet = null; } else { packetAre.WaitOne(TimeSpan.FromMilliseconds(1)); } } catch (Exception e) { if (conn.IsClosed || closing) { if (LOG.IsDebugEnabled) { // closing so this is expected LOG.DebugFormat("An exception was thrown while closing send thread for session 0x{0:X} : {1}", conn.SessionId, e.Message); } break; } else { // this is ugly, you have a better way speak up if (e is KeeperException.SessionExpiredException) { LOG.InfoFormat("{0}, closing socket connection", e.Message); } else if (e is SessionTimeoutException) { LOG.InfoFormat("{0}{1}", e.Message, RETRY_CONN_MSG); } else if (e is System.IO.EndOfStreamException) { LOG.InfoFormat("{0}{1}", e.Message, RETRY_CONN_MSG); } else { LOG.InfoFormat("Session 0x{0:X} for server {1}, unexpected error{2}, detail:{3}-{4}", conn.SessionId, null, RETRY_CONN_MSG, e.Message, e.StackTrace); } // a safe-net ...there's a packet about to send when an exception happen if (packet != null) { ConLossPacket(packet); } // clean up any queued packet Cleanup(); if (zooKeeper.State.IsAlive()) { conn.consumer.QueueEvent(new WatchedEvent(KeeperState.Disconnected, EventType.None, null)); } } } } // safe-net to ensure everything is clean up properly Cleanup(); // i don't think this is necessary, when we reached this block ....the state is surely not alive if (zooKeeper.State.IsAlive()) { conn.consumer.QueueEvent(new WatchedEvent(KeeperState.Disconnected, EventType.None, null)); } if (LOG.IsDebugEnabled) { LOG.Debug("SendThread exitedloop."); } }