package edu.washington.escience.myria.parallel.ipc; import java.util.concurrent.atomic.AtomicBoolean; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.FailedChannelFuture; import org.jboss.netty.channel.SucceededChannelFuture; import edu.washington.escience.myria.operator.network.Consumer; /** * * An {@link StreamInputChannel} represents a partition of a {@link Consumer} input . * * @param <PAYLOAD> the type of payload that this input channel will receive. * */ public class StreamInputChannel<PAYLOAD> extends StreamIOChannel { /** The logger for this class. */ static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(StreamInputChannel.class); /** * The input buffer into which the messages from this channel should be pushed. * */ private final StreamInputBuffer<PAYLOAD> inputBuffer; /** * If this logical input channel is paused. */ private final AtomicBoolean paused = new AtomicBoolean(false); /** * release this logical input channel. */ public final void release() { Channel channel = detachIOChannel(); if (channel != null && channel.isConnected()) { ChannelContext.resumeRead(channel); } } /** * @param ib the destination input buffer. * @param ecID exchange channel ID. * */ StreamInputChannel(final StreamIOChannelID ecID, final StreamInputBuffer<PAYLOAD> ib) { super(ecID); inputBuffer = ib; } @Override public final String toString() { return "StreamInput{ ID: " + getID() + ", IOChannel: " + ChannelContext.channelToString(getIOChannel()) + " }"; } /** * @return the destination input buffer. * */ final StreamInputBuffer<PAYLOAD> getInputBuffer() { return inputBuffer; } /** * pause the read from this logical input channel, no matter the state of the underlying physical input channel. * * @return future of this operation. */ public ChannelFuture pauseRead() { if (this.paused.compareAndSet(false, true)) { Channel ch = getIOChannel(); if (ch != null) { return ChannelContext.pauseRead(ch); } } // if there is no physical channel attached, or it's already paused. return new SucceededChannelFuture(NullChannel.NULL); } /** * Resume the read of all IO channels that are inputs of this input buffer. * * @return ChannelGroupFuture denotes the future of the resume read action. * */ public ChannelFuture resumeRead() { if (this.paused.compareAndSet(true, false)) { Channel ch = getIOChannel(); if (ch != null) { return ChannelContext.resumeRead(ch); } return new FailedChannelFuture(NullChannel.NULL, new NullPointerException()); } return new SucceededChannelFuture(NullChannel.NULL); } }