Package org.voltdb.client

Source Code of org.voltdb.client.MyCallback2

/* This file is part of VoltDB.
* Copyright (C) 2008-2014 VoltDB Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package org.voltdb.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import junit.framework.TestCase;

import org.voltdb.ServerThread;
import org.voltdb.TableHelper;
import org.voltdb.VoltDB;
import org.voltdb.VoltDB.Configuration;
import org.voltdb.VoltTable;
import org.voltdb.compiler.CatalogBuilder;
import org.voltdb.compiler.DeploymentBuilder;
import org.voltdb.utils.MiscUtils;

public class TestClientFeatures extends TestCase {

    ServerThread localServer;
    DeploymentBuilder depBuilder;

    @Override
    public void setUp()
    {
        try {
            CatalogBuilder catBuilder = new CatalogBuilder();
            catBuilder.addSchema(getClass().getResource("clientfeatures.sql"));
            catBuilder.addProcedures(ArbitraryDurationProc.class);

            boolean success = catBuilder.compile(Configuration.getPathToCatalogForTest("timeouts.jar"));
            assert(success);

            depBuilder = new DeploymentBuilder(1, 1, 0);
            depBuilder.writeXML(Configuration.getPathToCatalogForTest("timeouts.xml"));

            VoltDB.Configuration config = new VoltDB.Configuration();
            config.m_pathToCatalog = Configuration.getPathToCatalogForTest("timeouts.jar");
            config.m_pathToDeployment = Configuration.getPathToCatalogForTest("timeouts.xml");
            localServer = new ServerThread(config);
            localServer.start();
            localServer.waitForInitialization();
        }
        catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    @Override
    public void tearDown() throws Exception {
        localServer.shutdown();
    }

    class CSL extends ClientStatusListenerExt {

        AtomicBoolean m_gotCall = new AtomicBoolean(false);

        @Override
        public synchronized void lateProcedureResponse(ClientResponse r, String hostname, int port) {
            m_gotCall.set(true);
        }

        public boolean waitForCall(long timeout) {
            long start = System.currentTimeMillis();
            long now = start;
            while ((m_gotCall.get() == false) && ((now - start) < timeout)) {
                Thread.yield();
                now = System.currentTimeMillis();
            }
            return m_gotCall.get();
        }
    }

    public void testPerCallTimeout() throws Exception {
        CSL csl = new CSL();

        ClientConfig config = new ClientConfig(null, null, csl);
        config.setProcedureCallTimeout(500);
        Client client = ClientFactory.createClient(config);
        client.createConnection("localhost");

        ClientResponse response = client.callProcedure("ArbitraryDurationProc", 0);
        assertEquals(ClientResponse.SUCCESS, response.getStatus());

        try {
            client.callProcedure("ArbitraryDurationProc", 3000);
            fail();
        }
        catch (ProcCallException e) {
            assertTrue(e.getMessage().startsWith("No response received in the allotted time"));
        }
        // make sure the callback gets called
        assertTrue(csl.waitForCall(6000));

        //
        // From here down test special exception for slow snapshots or catalogs updates
        // - Both features are pro only
        //

        if (MiscUtils.isPro()) {
            // build a catalog with a ton of indexes so catalog update will be slow
            CatalogBuilder builder = new CatalogBuilder();
            builder.addSchema(getClass().getResource("clientfeatures-wellindexed.sql"));
            builder.addProcedures(ArbitraryDurationProc.class);
            byte[] catalogToUpdate = builder.compileToBytes();
            assert(catalogToUpdate != null);

            // make a copy of the table from ddl for loading
            // (shouldn't have to do this, but for now, the table loader requires
            //  a VoltTable, and can't read schema. Could fix by using this VoltTable
            //  to generate schema or by teaching to loader how to discover tables)
            VoltTable t = TableHelper.quickTable("indexme (pkey:bigint, " +
                                                          "c01:varchar63, " +
                                                          "c02:varchar63, " +
                                                          "c03:varchar63, " +
                                                          "c04:varchar63, " +
                                                          "c05:varchar63, " +
                                                          "c06:varchar63, " +
                                                          "c07:varchar63, " +
                                                          "c08:varchar63, " +
                                                          "c09:varchar63, " +
                                                          "c10:varchar63) " +
                                                          "PKEY(pkey)");
            // get a client with a normal timout
            Client client2 = ClientFactory.createClient();
            client2.createConnection("localhost");
            TableHelper.fillTableWithBigintPkey(t, 400, 0, client2, new Random(), 0, 1);

            long start;
            double duration;

            // run a catalog update that *might* normally timeout
            start = System.nanoTime();
            response = client.callProcedure("@UpdateApplicationCatalog", catalogToUpdate, depBuilder.getXML());
            duration = (System.nanoTime() - start) / 1000000000.0;
            System.out.printf("Catalog update duration in seconds: %.2f\n", duration);
            assertEquals(ClientResponse.SUCCESS, response.getStatus());

            // run a blocking snapshot that *might* normally timeout
            start = System.nanoTime();
            response = client.callProcedure("@SnapshotSave", Configuration.getPathToCatalogForTest(""), "slow", 1);
            duration = (System.nanoTime() - start) / 1000000000.0;
            System.out.printf("Snapshot save duration in seconds: %.2f\n", duration);
            assertEquals(ClientResponse.SUCCESS, response.getStatus());
        }
    }

    public void testMaxTimeout() throws NoConnectionsException, IOException, ProcCallException {
        CSL csl = new CSL();

        ClientConfig config = new ClientConfig(null, null, csl);
        config.setProcedureCallTimeout(0);
        Client client = ClientFactory.createClient(config);
        client.createConnection("localhost");

        ClientResponse response = client.callProcedure("ArbitraryDurationProc", 0);
        assertEquals(ClientResponse.SUCCESS, response.getStatus());

        client.callProcedure("ArbitraryDurationProc", 3000);
        assertEquals(ClientResponse.SUCCESS, response.getStatus());
    }

    public void testQueryTimeout() throws NoConnectionsException, IOException, ProcCallException {
        CSL csl = new CSL();

        ClientConfig config = new ClientConfig(null, null, csl);
        config.setProcedureCallTimeout(0);
        Client client = ClientFactory.createClient(config);
        client.createConnection("localhost");

        ClientResponse response = client.callProcedure("ArbitraryDurationProc", 0);
        assertEquals(ClientResponse.SUCCESS, response.getStatus());
        boolean exceptionCalled = false;
        try {
            // Query timeout is in seconds second arg.
            ((ClientImpl) client).callProcedureWithTimeout("ArbitraryDurationProc", 3, TimeUnit.SECONDS, 6000);
        } catch (ProcCallException ex) {
            assertEquals(ClientResponse.CONNECTION_TIMEOUT, ex.m_response.getStatus());
            exceptionCalled = true;
        }
        assertTrue(exceptionCalled);

        //larger timeout than proc wait duration
        exceptionCalled = false;
        try {
            // Query timeout is in seconds second arg.
            ((ClientImpl) client).callProcedureWithTimeout("ArbitraryDurationProc", 30, TimeUnit.SECONDS, 6000);
        } catch (ProcCallException ex) {
            exceptionCalled = true;
        }
        assertFalse(exceptionCalled);

        //no timeout of 0
        try {
            // Query timeout is in seconds second arg.
            ((ClientImpl) client).callProcedureWithTimeout("ArbitraryDurationProc", 0, TimeUnit.SECONDS, 2000);
        } catch (ProcCallException ex) {
            exceptionCalled = true;
        }
        assertFalse(exceptionCalled);

        final CountDownLatch latch = new CountDownLatch(1);
        class MyCallback implements ProcedureCallback {
            @Override
            public void clientCallback(ClientResponse clientResponse) throws Exception {
                assert (clientResponse.getStatus() == ClientResponse.CONNECTION_TIMEOUT);
                System.out.println("Async Query timeout called..");
                latch.countDown();
            }

        }
        // Query timeout is in seconds third arg.
        //Async versions
        ((ClientImpl) client).callProcedureWithTimeout(new MyCallback(), "ArbitraryDurationProc", 3, TimeUnit.SECONDS, 6000);
        try {
            latch.await();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            fail();
        }

        //Async versions - does not timeout.
        final CountDownLatch latch2 = new CountDownLatch(1);
        class MyCallback2 implements ProcedureCallback {

            @Override
            public void clientCallback(ClientResponse clientResponse) throws Exception {
                assert (clientResponse.getStatus() == ClientResponse.SUCCESS);
                latch2.countDown();
            }

        }
        // Query timeout is in seconds third arg.
        ((ClientImpl) client).callProcedureWithTimeout(new MyCallback2(), "ArbitraryDurationProc", 30, TimeUnit.SECONDS, 6000);
        try {
            latch2.await();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            fail();
        }

        //Async versions - 0 timeout.
        final CountDownLatch latch3 = new CountDownLatch(1);
        class MyCallback3 implements ProcedureCallback {

            @Override
            public void clientCallback(ClientResponse clientResponse) throws Exception {
                assert (clientResponse.getStatus() == ClientResponse.SUCCESS);
                latch3.countDown();
            }

        }
        // Query timeout is in seconds third arg.
        ((ClientImpl) client).callProcedureWithTimeout(new MyCallback3(), "ArbitraryDurationProc", 0, TimeUnit.SECONDS, 6000);
        try {
            latch3.await();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            fail();
        }

        final CountDownLatch latch4 = new CountDownLatch(1);
        class MyCallback4 implements ProcedureCallback {

            @Override
            public void clientCallback(ClientResponse clientResponse) throws Exception {
                assert (clientResponse.getStatus() == ClientResponse.CONNECTION_TIMEOUT);
                latch4.countDown();
            }

        }

        /*
         * Check that a super tiny timeout triggers fast
         */
        ((ClientImpl) client).callProcedureWithTimeout(new MyCallback4(), "ArbitraryDurationProc", 50, TimeUnit.NANOSECONDS, 6000);
        final long start = System.nanoTime();
        try {
            latch4.await();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            fail();
        }
        final long delta = System.nanoTime() - start;
        assertTrue(TimeUnit.NANOSECONDS.toSeconds(delta) < 1);
    }

    /**
     * Verify a client can reconnect to a cluster that has been restarted.
     */
    public void testReconnect() throws Exception {
        ClientConfig config = new ClientConfig();
        Client client = ClientFactory.createClient(config);
        client.createConnection("localhost");

        tearDown();

        for (int i = 0; (i < 40) && (client.getConnectedHostList().size() > 0); i++) {
            Thread.sleep(500);
        }
        assertTrue(client.getConnectedHostList().isEmpty());

        setUp();

        client.createConnection("localhost");

        assertFalse(client.getConnectedHostList().isEmpty());
    }

    /**
     * Verify a client can reconnect automatically if reconnect on connection loss feature is turned on
     */
    public void testAutoReconnect() throws Exception {
        ClientConfig config = new ClientConfig();
        config.setReconnectOnConnectionLoss(true);
        Client client = ClientFactory.createClient(config);
        client.createConnection("localhost");

        tearDown();

        for (int i = 0; (i < 40) && (client.getConnectedHostList().size() > 0); i++) {
            Thread.sleep(500);
        }
        assertTrue(client.getConnectedHostList().isEmpty());

        // sleep before server restart to force some reconnect failures
        Thread.sleep(2000);

        setUp();

        for (int i = 0; i < 40; i++) {
            if (client.getConnectedHostList().size() > 0) {
                return;
            }
            Thread.sleep(500);
        }

        fail("Client should have been reconnected");
    }

    public void testGetAddressList() throws UnknownHostException, IOException, InterruptedException {
        CSL csl = new CSL();

        ClientConfig config = new ClientConfig(null, null, csl);
        config.setProcedureCallTimeout(0);
        Client client = ClientFactory.createClient(config);

        List<InetSocketAddress> addrs = client.getConnectedHostList();
        assertEquals(0, addrs.size());
        client.createConnection("localhost");
        addrs = client.getConnectedHostList();
        assertEquals(1, addrs.size());
        assertEquals(VoltDB.DEFAULT_PORT, addrs.get(0).getPort());
        client.close();
        addrs = client.getConnectedHostList();
        assertEquals(0, addrs.size());
    }

    public void testBackpressureTimeout() throws Exception {
        final ClientImpl client = (ClientImpl)ClientFactory.createClient();
        client.createConnection("localhost");
        client.backpressureBarrier(System.nanoTime(), TimeUnit.DAYS.toNanos(1));
        client.m_listener.backpressure(true);

        long start = System.nanoTime();
        assertTrue(client.backpressureBarrier(System.nanoTime(), TimeUnit.MILLISECONDS.toNanos(200)));
        long delta = System.nanoTime() - start;
        assertTrue(delta > TimeUnit.MILLISECONDS.toNanos(200));
        assertTrue(delta < TimeUnit.MINUTES.toNanos(1));

        start = System.nanoTime();
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(20);
                    client.m_listener.backpressure(false);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
        assertFalse(client.backpressureBarrier(System.nanoTime(), TimeUnit.MINUTES.toNanos(1)));
        assertTrue(delta < TimeUnit.MINUTES.toNanos(1));
        assertTrue(delta > TimeUnit.MILLISECONDS.toNanos(20));
    }
}
TOP

Related Classes of org.voltdb.client.MyCallback2

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.