biz.c24.io.spring.batch.reader.performance.util.ItemReaderJobRunner.java Source code

Java tutorial

Introduction

Here is the source code for biz.c24.io.spring.batch.reader.performance.util.ItemReaderJobRunner.java

Source

/*
 * Copyright 2012 C24 Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *          http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package biz.c24.io.spring.batch.reader.performance.util;

import org.springframework.batch.item.ItemReader;

import biz.c24.io.api.data.ComplexDataObject;
import biz.c24.io.spring.batch.reader.C24ItemReader;

/**
 * Abstract test harness to call read on a C24ItemReader until the underlying Reader is exhausted.
 * 
 * @author Andrew Elmore
 *
 */
public abstract class ItemReaderJobRunner {
    private long runTime;
    private long recordsProcessed;
    private int numThreads;

    public ItemReaderJobRunner(int numThreads) {
        this.numThreads = numThreads;
    }

    /**
     * Override this to create the C24ItemReader to be exercised during the test
     * @return The C24ItemReader to be exercised during the test.
     */
    protected abstract C24ItemReader<ComplexDataObject> createReader();

    /**
     * Executes the test.
     * Fires up the specified number of threads to invoke read on the C24ItemReader until there
     * is no more data to read.
     * Tracks the number of items read and the cumulative processing time.
     */
    public void runJob() {

        ItemReaderJobRunner.Worker<ComplexDataObject>[] workers = new ItemReaderJobRunner.Worker[numThreads];

        C24ItemReader<ComplexDataObject> reader = createReader();

        for (int i = 0; i < workers.length; i++) {
            workers[i] = new ItemReaderJobRunner.Worker<ComplexDataObject>();
            workers[i].setReader(reader);
            workers[i].start();
        }

        recordsProcessed = 0;
        long startTime = System.nanoTime();

        for (int i = 0; i < workers.length; i++) {
            try {
                workers[i].join(200000);
                recordsProcessed += workers[i].getCount();
                if (workers[i].getException() != null) {
                    throw new RuntimeException(workers[i].getException());
                }

            } catch (InterruptedException e) {
                throw new RuntimeException("Interrupted waiting on thread");
            }
            if (workers[i].isAlive()) {
                throw new RuntimeException("Timed out waiting for thread to complete its work");
            }
        }

        runTime = System.nanoTime() - startTime;

        reader.cleanup();
    }

    public long getRecordsProcessed() {
        return this.recordsProcessed;
    }

    public long getRunTime() {
        return this.runTime;
    }

    private static class Worker<T extends ComplexDataObject> implements Runnable {
        private ItemReader<T> reader;
        private Exception ex = null;
        private long count = 0;
        private Thread thread = new Thread(this);

        public Worker() {
        }

        public void setReader(ItemReader<T> itemReader) {
            this.reader = itemReader;
        }

        public void start() {
            thread.start();
        }

        public void join(long timeoutMs) throws InterruptedException {
            thread.join(timeoutMs);
        }

        public boolean isAlive() {
            return thread.isAlive();
        }

        public long getCount() {
            return count;
        }

        public void run() {
            count = 0;
            ex = null;
            try {
                while (reader.read() != null) {
                    count++;
                }
            } catch (Exception e) {
                ex = e;
                throw new RuntimeException(e);
            }
        }

        public Exception getException() {
            return ex;
        }
    }

}