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

Java tutorial

Introduction

Here is the source code for com.espertech.esper.regression.nwtable.TestTableMTGroupedAccessReadIntoTableWriteAggColConsistency.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.client.SupportConfigFactory;
import com.espertech.esper.util.CollectionUtil;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

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

    private EPServiceProvider epService;

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

    /**
     * Table:
     *   create table vartotal (key string primary key, tc0 sum(int), tc1 sum(int) ... tc9 sum(int))
     *
     * Seed the table with a number of groups, no new ones are added or deleted during the test.
     * For a given number of seconds and a given number of groups:
     * - Single writer updates a group (round-robin), each group associates with 10 columns .
     * - N readers pull a group's columns, round-robin, check that all 10 values are consistent.
     * - The 10 values are sum-int totals that are expected to all have the same value.
     */
    public void testMT() throws Exception {
        tryMT(10, 3);
    }

    private void tryMT(int numGroups, int numSeconds) throws Exception {
        String eplCreateVariable = "create table vartotal (key string primary key, "
                + CollectionUtil.toString(getDeclareCols()) + ")";
        epService.getEPAdministrator().createEPL(eplCreateVariable);

        String eplInto = "into table vartotal select " + CollectionUtil.toString(getIntoCols())
                + " from Local10ColEvent group by groupKey";
        epService.getEPAdministrator().createEPL(eplInto);

        // initialize groups
        String[] groups = new String[numGroups];
        for (int i = 0; i < numGroups; i++) {
            groups[i] = "G" + i;
            epService.getEPRuntime().sendEvent(new Local10ColEvent(groups[i], 0));
        }

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

        // start
        Thread t1 = new Thread(writeRunnable);
        Thread t2 = new Thread(readRunnable);
        t1.start();
        t2.start();

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

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

        // join
        log.info("Waiting for completion");
        t1.join();
        t2.join();

        assertNull(writeRunnable.getException());
        assertNull(readRunnable.getException());
        assertTrue(writeRunnable.numEvents > 100);
        assertTrue(readRunnable.numQueries > 100);
        System.out.println(
                "Send " + writeRunnable.numEvents + " and performed " + readRunnable.numQueries + " reads");
    }

    private Collection<String> getDeclareCols() {
        List<String> cols = new ArrayList<String>();
        for (int i = 0; i < 10; i++) { // 10 columns, not configurable
            cols.add("tc" + i + " sum(int)");
        }
        return cols;
    }

    private Collection<String> getIntoCols() {
        List<String> cols = new ArrayList<String>();
        for (int i = 0; i < 10; i++) { // 10 columns, not configurable
            cols.add("sum(c" + i + ") as tc" + i);
        }
        return cols;
    }

    public static class WriteRunnable implements Runnable {

        private final EPServiceProvider epService;
        private final String[] groups;

        private RuntimeException exception;
        private boolean shutdown;
        private int numEvents;

        public WriteRunnable(EPServiceProvider epService, String[] groups) {
            this.epService = epService;
            this.groups = groups;
        }

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

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

            try {
                while (!shutdown) {
                    int groupNum = numEvents % groups.length;
                    epService.getEPRuntime().sendEvent(new Local10ColEvent(groups[groupNum], numEvents));
                    numEvents++;
                }
            } 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 String[] groups;

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

        public ReadRunnable(EPServiceProvider epService, String[] groups) {
            this.epService = epService;
            this.groups = groups;
        }

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

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

            try {
                String eplSelect = "select vartotal[theString] as out from SupportBean";
                SupportUpdateListener listener = new SupportUpdateListener();
                epService.getEPAdministrator().createEPL(eplSelect).addListener(listener);

                while (!shutdown) {
                    int groupNum = numQueries % groups.length;
                    epService.getEPRuntime().sendEvent(new SupportBean(groups[groupNum], 0));
                    EventBean event = listener.assertOneGetNewAndReset();
                    assertEvent((Map) event.get("out"));
                    numQueries++;
                }
            } catch (RuntimeException ex) {
                log.error("Exception encountered: " + ex.getMessage(), ex);
                exception = ex;
            }

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

        private void assertEvent(Map info) {
            Object tc0 = info.get("tc0");
            for (int i = 1; i < 10; i++) {
                assertEquals(tc0, info.get("tc" + i));
            }
        }

        public RuntimeException getException() {
            return exception;
        }
    }

    public static final class Local10ColEvent {
        private final String groupKey;
        private final int c0;
        private final int c1;
        private final int c2;
        private final int c3;
        private final int c4;
        private final int c5;
        private final int c6;
        private final int c7;
        private final int c8;
        private final int c9;

        public Local10ColEvent(String groupKey, int value) {
            this.groupKey = groupKey;
            this.c0 = value;
            this.c1 = value;
            this.c2 = value;
            this.c3 = value;
            this.c4 = value;
            this.c5 = value;
            this.c6 = value;
            this.c7 = value;
            this.c8 = value;
            this.c9 = value;
        }

        public String getGroupKey() {
            return groupKey;
        }

        public int getC0() {
            return c0;
        }

        public int getC1() {
            return c1;
        }

        public int getC2() {
            return c2;
        }

        public int getC3() {
            return c3;
        }

        public int getC4() {
            return c4;
        }

        public int getC5() {
            return c5;
        }

        public int getC6() {
            return c6;
        }

        public int getC7() {
            return c7;
        }

        public int getC8() {
            return c8;
        }

        public int getC9() {
            return c9;
        }
    }
}