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);
     
 }
Ejemplo n.º 13
0
        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.");
            }
        }
Ejemplo n.º 14
0
 private void addPacketFirst(Packet p)
 {
     outgoingQueue.AddFirst(p);
 }