예제 #1
0
        public async Task testTwoConsequitiveCallsToNextReturnDifferentElement()
        {
            HostProvider hostProvider = getHostProvider(2);
            await hostProvider.next(0);

            Assert.assertNotEquals((await hostProvider.next(0)).ToString(), (await hostProvider.next(0)).ToString());
        }
예제 #2
0
        public async Task testNextGoesRound()
        {
            HostProvider hostProvider = getHostProvider(2);
            var          first        = await hostProvider.next(0);

            await hostProvider.next(0);

            Assert.assertEquals(first, await hostProvider.next(0));
        }
예제 #3
0
        public async Task testOnConnectDoesNotReset()
        {
            HostProvider hostProvider = getHostProvider(2);
            var          first        = await hostProvider.next(0);

            hostProvider.onConnected();
            var second = await hostProvider.next(0);

            Assert.assertNotEquals(first, second);
        }
예제 #4
0
        public async Task testNextGoesRound()
        {
            HostProvider hostProvider = getHostProvider(1);
            await hostProvider.next(0);

            var first = await hostProvider.next(0);

            var second = await hostProvider.next(0);

            Xunit.Assert.Equal(first, second);
        }
예제 #5
0
        public async Task testResetAfterConnectPutsFirst()
        {
            HostProvider hostProvider = getHostProvider(20);
            await hostProvider.next(0);

            var endpoint = await hostProvider.next(0);

            hostProvider.onConnected();
            for (int i = 0; i < 19; i++)
            {
                await hostProvider.next(0);
            }
            Assert.assertEquals(endpoint.ToString(), (await hostProvider.next(0)).ToString());
        }
예제 #6
0
        public async Task testNextDoesNotSleepForZero()
        {
            byte         size         = 2;
            HostProvider hostProvider = getHostProvider(size);

            while (size > 0)
            {
                await hostProvider.next(0);

                --size;
            }
            long start = TimeHelper.ElapsedMiliseconds;
            await hostProvider.next(0);

            long stop = TimeHelper.ElapsedMiliseconds;

            Assert.assertTrue(5 > stop - start);
        }
예제 #7
0
        public async Task testNextGoesRoundAndSleeps()
        {
            byte         size         = 2;
            HostProvider hostProvider = getHostProvider(size);

            while (size > 0)
            {
                await hostProvider.next(0);

                --size;
            }
            long start = TimeHelper.ElapsedMiliseconds;
            await hostProvider.next(1000);

            long stop = TimeHelper.ElapsedMiliseconds;

            Assert.assertTrue(900 <= stop - start);
        }
예제 #8
0
        private async Task startConnect()
        {
            state.Value = ZooKeeper.States.CONNECTING;
            ResolvedEndPoint addr;

            if (rwServerAddress != null)
            {
                addr            = rwServerAddress;
                rwServerAddress = null;
            }
            else
            {
                addr = await hostProvider.next(1000).ConfigureAwait(false);
            }

            logStartConnect(addr);
            clientCnxnSocket.connect(addr);
        }
예제 #9
0
        public async Task TestFirstAndSecondAreSame()
        {
            HostProvider hostProvider = getHostProvider(20);

            Assert.assertEquals((await hostProvider.next(0)).ToString(), (await hostProvider.next(0)).ToString());
        }
예제 #10
0
        private async Task startSendTask()
        {
            try {
                clientCnxnSocket.introduce(sessionId);
                clientCnxnSocket.updateNow();
                clientCnxnSocket.updateLastSendAndHeard();
                int              to;
                long             lastPingRwServer       = TimeHelper.ElapsedMiliseconds;
                const int        MAX_SEND_PING_INTERVAL = 10000; //10 seconds
                ResolvedEndPoint serverAddress          = null;
                while (getState().isAlive())
                {
                    try {
                        if (!clientCnxnSocket.isConnected())
                        {
                            if (!isFirstConnect)
                            {
                                await Task.Delay(r.Next(1000)).ConfigureAwait(false);
                            }
                            else
                            {
                                await hostProvider.next(1000).ConfigureAwait(false);
                            }
                            // don't re-establish connection if we are closing
                            if (closing.Value || !getState().isAlive())
                            {
                                break;
                            }
                            if (rwServerAddress != null)
                            {
                                serverAddress   = rwServerAddress;
                                rwServerAddress = null;
                            }
                            else
                            {
                                serverAddress = await hostProvider.next(1000).ConfigureAwait(false);
                            }
                            startConnect(serverAddress);
                            clientCnxnSocket.updateLastSendAndHeard();
                        }

                        if (getState().isConnected())
                        {
                            to = readTimeout - clientCnxnSocket.getIdleRecv();
                        }
                        else
                        {
                            to = connectTimeout - clientCnxnSocket.getIdleRecv();
                        }

                        if (to <= 0)
                        {
                            string warnInfo;
                            warnInfo = "Client session timed out, have not heard from server in "
                                       + clientCnxnSocket.getIdleRecv()
                                       + "ms"
                                       + " for sessionid 0x"
                                       + clientCnxnSocket.sessionId.ToHexString();
                            LOG.warn(warnInfo);
                            throw new SessionTimeoutException(warnInfo);
                        }
                        if (getState().isConnected())
                        {
                            // 1000(1 second) is to prevent race condition missing to send the second ping
                            // also make sure not to send too many pings when readTimeout is small
                            int timeToNextPing = readTimeout / 2 - clientCnxnSocket.getIdleSend() -
                                                 ((clientCnxnSocket.getIdleSend() > 1000) ? 1000 : 0);
                            // send a ping request either time is due or no packet sent out within MAX_SEND_PING_INTERVAL
                            if (timeToNextPing <= 0 || clientCnxnSocket.getIdleSend() > MAX_SEND_PING_INTERVAL)
                            {
                                sendPing();
                                clientCnxnSocket.updateLastSend();
                            }
                            else
                            {
                                if (timeToNextPing < to)
                                {
                                    to = timeToNextPing;
                                }
                            }
                        }
                        // If we are in read-only mode, seek for read/write server
                        if (getState() == ZooKeeper.States.CONNECTEDREADONLY)
                        {
                            long now = TimeHelper.ElapsedMiliseconds;
                            int  idlePingRwServer = (int)(now - lastPingRwServer);
                            if (idlePingRwServer >= pingRwTimeout)
                            {
                                lastPingRwServer = now;
                                idlePingRwServer = 0;
                                pingRwTimeout    =
                                    Math.Min(2 * pingRwTimeout, maxPingRwTimeout);
                                await pingRwServer().ConfigureAwait(false);
                            }
                            to = Math.Min(to, pingRwTimeout - idlePingRwServer);
                        }
                        if (to > 0 && !clientCnxnSocket.somethingIsPending.IsCompleted)
                        {
                            timer.Change(to, Timeout.Infinite);
                            await clientCnxnSocket.somethingIsPending;
                            timer.Change(Timeout.Infinite, Timeout.Infinite);
                        }
                        clientCnxnSocket.doTransport();
                    } catch (Exception e) {
                        if (closing.Value)
                        {
                            if (LOG.isDebugEnabled())
                            {
                                // closing so this is expected
                                LOG.debug("An exception was thrown while closing send task for session 0x" +
                                          getSessionId().ToHexString(), e);
                            }
                            break;
                        }
                        // this is ugly, you have a better way speak up
                        if (e is SessionExpiredException)
                        {
                            LOG.info("closing socket connection", e);
                        }
                        else if (e is SessionTimeoutException)
                        {
                            LOG.info(RETRY_CONN_MSG, e);
                        }
                        else if (e is EndOfStreamException)
                        {
                            LOG.info(RETRY_CONN_MSG, e);
                        }
                        else if (e is RWServerFoundException)
                        {
                            LOG.info(e);
                        }
                        else if (e is SocketException)
                        {
                            LOG.info(string.Format("Socket error occurred: {0}", serverAddress), e);
                        }
                        else
                        {
                            LOG.warn(string.Format("Session 0x{0} for server {1}, unexpected error{2}",
                                                   getSessionId().ToHexString(),
                                                   serverAddress,
                                                   RETRY_CONN_MSG),
                                     e);
                        }
                        cleanup();
                        if (getState().isAlive())
                        {
                            queueEvent(new WatchedEvent(
                                           Watcher.Event.EventType.None,
                                           Watcher.Event.KeeperState.Disconnected, null));
                        }
                        clientCnxnSocket.updateNow();
                        clientCnxnSocket.updateLastSendAndHeard();
                    }
                }

                cleanup();
                clientCnxnSocket.close();
                if (getState().isAlive())
                {
                    queueEvent(new WatchedEvent(Watcher.Event.EventType.None,
                                                Watcher.Event.KeeperState.Disconnected, null));
                }
            }
            catch (Exception e) {
                LOG.warn("Exception occurred in SendTask", e);
            }
            LOG.debug("SendTask exited loop for session: 0x"
                      + getSessionId().ToHexString());
        }