All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kaazing.robot.driver.netty.channel.CompositeChannelFuture2 Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2014 "Kaazing Corporation," (www.kaazing.com)
 *
 * This file is part of Robot.
 *
 * Robot is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see .
 */

package org.kaazing.robot.driver.netty.channel;

import java.util.concurrent.atomic.AtomicInteger;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelFutureProgressListener;
import org.jboss.netty.channel.DefaultChannelFuture;

/**
 * A {@link ChannelFuture} of {@link ChannelFuture}s. It is useful when you want to get notified when all
 * {@link ChannelFuture}s are complete.
 * @param  the type of the child futures.
 */
public class CompositeChannelFuture2 extends DefaultChannelFuture {

    private final NotifyingListener listener = new NotifyingListener();
    private final AtomicInteger unnotified = new AtomicInteger();
    private volatile boolean constructionFinished;

    // XXX Look into have a special-purpose constructor which only takes
    // two ChannelFutures, rather than an Iterable (whose length cannot be
    // known in advance). One of the ChannelFutures might already be a
    // CompositeChannelFuture2 itself, which is fine. By knowing that
    // we only have two components, we can initialize the AtomicInteger
    // to 2, and call it good.

    public CompositeChannelFuture2(Channel channel, boolean cancellable, Iterable kids) {
        super(channel, cancellable);

        for (E k : kids) {
            k.addListener(listener);
            unnotified.incrementAndGet();
        }

        constructionFinished = true;
        if (unnotified.get() == 0) {
            setSuccess();
        }
    }

    public CompositeChannelFuture2(Channel channel, Iterable kids) {
        this(channel, false, kids);
    }

    /**
     * Convenience constructor which takes a single {@link ChannelFuture}.
     */
    public CompositeChannelFuture2(Channel channel, ChannelFuture kid) {
        super(channel, false);

        kid.addListener(listener);
        unnotified.incrementAndGet();

        constructionFinished = true;
        if (unnotified.get() == 0) {
            setSuccess();
        }
    }

    private class NotifyingListener implements ChannelFutureListener, ChannelFutureProgressListener {

        @Override
        public void operationProgressed(ChannelFuture future, long amount, long current, long total) throws Exception {

            if (constructionFinished) {
                setProgress(amount, current, total);
            }
        }

        @Override
        public void operationComplete(ChannelFuture future) {
            if (unnotified.decrementAndGet() == 0 && constructionFinished) {

                if (future.isSuccess()) {
                    setSuccess();

                } else {
                    setFailure(future.getCause());
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy