co.cask.cdap.internal.app.queue.RoundRobinQueueReader.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.internal.app.queue.RoundRobinQueueReader.java

Source

/*
 * Copyright  2014 Cask Data, Inc.
 *
 * 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 co.cask.cdap.internal.app.queue;

import co.cask.cdap.app.queue.InputDatum;
import co.cask.cdap.app.queue.QueueReader;
import com.google.common.collect.Iterables;

import java.io.IOException;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

/**
 * A {@link QueueReader} that reads from a list of {@link QueueReader}
 * in Round-Robin fashion. It will try skipping empty inputs when dequeueing
 * until a non-empty one is found or has exhausted the list of underlying
 * {@link QueueReader}, which will return an empty input.
 *
 * @param <T> Type of input dequeued from this reader.
 */

public final class RoundRobinQueueReader<T> extends TimeTrackingQueueReader<T> {

    private final InputDatum<T> nullInput = new NullInputDatum<>();
    private final Iterator<QueueReader<T>> readers;

    public RoundRobinQueueReader(Iterable<QueueReader<T>> readers) {
        this.readers = Iterables.cycle(readers).iterator();
    }

    public InputDatum<T> tryDequeue(long timeout, TimeUnit timeoutUnit) throws IOException, InterruptedException {
        if (!readers.hasNext()) {
            return nullInput;
        }

        // Read an input from the underlying QueueReader
        QueueReader<T> begin = readers.next();
        InputDatum<T> input = begin.dequeue(timeout, timeoutUnit);

        // While the input is empty, keep trying to read from subsequent readers,
        // until a non-empty input is read or it loop back to the beginning reader.
        while (!input.needProcess()) {
            QueueReader<T> reader = readers.next();
            if (reader == begin) {
                return input;
            }
            input = reader.dequeue(0, TimeUnit.MILLISECONDS);
        }
        return input;
    }
}