com.espertech.esper.regression.nwtable.TestTableMTGroupedJoinReadMergeWriteSecondaryIndexUpd.java Source code

Java tutorial

Introduction

Here is the source code for com.espertech.esper.regression.nwtable.TestTableMTGroupedJoinReadMergeWriteSecondaryIndexUpd.java

Source

/*
 * *************************************************************************************
 *  Copyright (C) 2006-2015 EsperTech, Inc. All rights reserved.                       *
 *  http://www.espertech.com/esper                                                     *
 *  http://www.espertech.com                                                           *
 *  ---------------------------------------------------------------------------------- *
 *  The software in this package is published under the terms of the GPL license       *
 *  a copy of which has been included with this distribution in the license.txt file.  *
 * *************************************************************************************
 */

package com.espertech.esper.regression.nwtable;

import com.espertech.esper.client.Configuration;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.scopetest.SupportUpdateListener;
import com.espertech.esper.support.bean.SupportBean;
import com.espertech.esper.support.bean.SupportBean_S0;
import com.espertech.esper.support.bean.SupportBean_S1;
import com.espertech.esper.support.client.SupportConfigFactory;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TestTableMTGroupedJoinReadMergeWriteSecondaryIndexUpd extends TestCase {
    private static final Log log = LogFactory.getLog(TestTableMTGroupedJoinReadMergeWriteSecondaryIndexUpd.class);

    private static final int NUM_KEYS = 10;
    private static final int OFFSET_ADDED = 100000000;

    private EPServiceProvider epService;

    public void setUp() {
        Configuration config = SupportConfigFactory.getConfiguration();
        config.addEventType(SupportBean.class);
        config.addEventType(SupportBean_S0.class);
        config.addEventType(SupportBean_S1.class);
        epService = EPServiceProviderManager.getDefaultProvider(config);
        epService.initialize();
    }

    /**
     * Tests concurrent updates on a secondary index also read by a join:
     *   create table MyTable (key string primary key, value int)
     *   create index MyIndex on MyTable (value)
     *   select * from SupportBean_S0, MyTable where intPrimitive = id
     *
     *   Prefill MyTable with MyTable={key='A_N', value=N} with N between 0 and NUM_KEYS-1
     *
     *   For x seconds:
     *   Single reader thread sends SupportBean events, asserts that either one or two rows are found (A_N and maybe B_N)
     *   Single writer thread inserts MyTable={key='B_N', value=100000+N} and deletes each row.
     */
    public void testMT() throws Exception {
        tryMT(2);
    }

    private void tryMT(int numSeconds) throws Exception {
        String epl = "create table MyTable (key1 string primary key, value int);\n"
                + "create index MyIndex on MyTable (value);\n"
                + "on SupportBean merge MyTable where theString = key1 when not matched then insert select theString as key1, intPrimitive as value;\n"
                + "@name('out') select * from SupportBean_S0, MyTable where value = id;\n"
                + "on SupportBean_S1 delete from MyTable where key1 like 'B%';\n";
        epService.getEPAdministrator().getDeploymentAdmin().parseDeploy(epl);

        // preload A_n events
        for (int i = 0; i < NUM_KEYS; i++) {
            epService.getEPRuntime().sendEvent(new SupportBean("A_" + i, i));
        }

        WriteRunnable writeRunnable = new WriteRunnable(epService);
        ReadRunnable readRunnable = new ReadRunnable(epService);

        // start
        Thread threadWrite = new Thread(writeRunnable);
        Thread threadRead = new Thread(readRunnable);
        threadWrite.start();
        threadRead.start();

        // wait
        Thread.sleep(numSeconds * 1000);

        // shutdown
        writeRunnable.setShutdown(true);
        readRunnable.setShutdown(true);

        // join
        log.info("Waiting for completion");
        threadWrite.join();
        threadRead.join();

        assertNull(writeRunnable.getException());
        assertNull(readRunnable.getException());
        System.out.println(
                "Write loops " + writeRunnable.numLoops + " and performed " + readRunnable.numQueries + " reads");
        assertTrue(writeRunnable.numLoops > 1);
        assertTrue(readRunnable.numQueries > 100);
    }

    public static class WriteRunnable implements Runnable {

        private final EPServiceProvider epService;

        private RuntimeException exception;
        private boolean shutdown;
        private int numLoops;

        public WriteRunnable(EPServiceProvider epService) {
            this.epService = epService;
        }

        public void setShutdown(boolean shutdown) {
            this.shutdown = shutdown;
        }

        public void run() {
            log.info("Started event send for write");

            try {
                while (!shutdown) {
                    // write additional B_n events
                    for (int i = 0; i < 10000; i++) {
                        epService.getEPRuntime().sendEvent(new SupportBean("B_" + i, i + OFFSET_ADDED));
                    }
                    // delete B_n events
                    epService.getEPRuntime().sendEvent(new SupportBean_S1(0));
                    numLoops++;
                }
            } catch (RuntimeException ex) {
                log.error("Exception encountered: " + ex.getMessage(), ex);
                exception = ex;
            }

            log.info("Completed event send for write");
        }

        public RuntimeException getException() {
            return exception;
        }
    }

    public static class ReadRunnable implements Runnable {

        private final EPServiceProvider epService;
        private final SupportUpdateListener listener;

        private RuntimeException exception;
        private boolean shutdown;
        private int numQueries;

        public ReadRunnable(EPServiceProvider epService) {
            this.epService = epService;
            listener = new SupportUpdateListener();
            epService.getEPAdministrator().getStatement("out").addListener(listener);
        }

        public void setShutdown(boolean shutdown) {
            this.shutdown = shutdown;
        }

        public void run() {
            log.info("Started event send for read");

            try {
                while (!shutdown) {
                    for (int i = 0; i < NUM_KEYS; i++) {
                        epService.getEPRuntime().sendEvent(new SupportBean_S0(i));
                        EventBean[] events = listener.getAndResetLastNewData();
                        assertTrue(events.length > 0);
                    }
                    numQueries++;
                }
            } catch (RuntimeException ex) {
                log.error("Exception encountered: " + ex.getMessage(), ex);
                exception = ex;
            }

            log.info("Completed event send for read");
        }

        public RuntimeException getException() {
            return exception;
        }
    }
}