package edu.uw.zookeeper.net; import java.net.SocketAddress; import java.util.concurrent.Executor; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.util.concurrent.ListenableFuture; import edu.uw.zookeeper.common.Automaton; import edu.uw.zookeeper.common.Eventful; /** * Asynchronous network channel. * * @see edu.uw.zookeeper.netty * @see edu.uw.zookeeper.net.intravm */ public interface Connection<I,O, C extends Connection<I,O,C>> extends Eventful<Connection.Listener<? super O>>, Executor { public static interface Listener<O> { void handleConnectionState(Automaton.Transition<Connection.State> state); void handleConnectionRead(O message); } public static enum State implements Function<State, Optional<Automaton.Transition<State>>> { CONNECTION_OPENING { @Override public Optional<Automaton.Transition<State>> apply(State nextState) { switch (nextState) { case CONNECTION_OPENING: return Optional.absent(); default: return Optional.of(Automaton.Transition.<State>create(this, nextState)); } } }, CONNECTION_OPENED { @Override public Optional<Automaton.Transition<State>> apply(State nextState) { switch (nextState) { case CONNECTION_CLOSING: case CONNECTION_CLOSED: return Optional.of(Automaton.Transition.<State>create(this, nextState)); default: return Optional.absent(); } } }, CONNECTION_CLOSING { @Override public Optional<Automaton.Transition<State>> apply(State nextState) { switch (nextState) { case CONNECTION_CLOSED: return Optional.of(Automaton.Transition.<State>create(this, nextState)); default: return Optional.absent(); } } }, CONNECTION_CLOSED { @Override public Optional<Automaton.Transition<State>> apply(State nextState) { return Optional.absent(); } }; } /** * Get current Connection.State. * * @return current state */ State state(); /** * Get local SocketAddress. * * @return local SocketAddress */ SocketAddress localAddress(); /** * Get remote SocketAddress. * * @return remote SocketAddress */ SocketAddress remoteAddress(); /** * Trigger a read. * * @return this */ C read(); /** * Asynchronously send a message. * * @param message I to send * @return ListenableFuture that returns {@code message} */ <T extends I> ListenableFuture<T> write(T message); /** * Trigger a flush of written messages. * * @return this */ C flush(); /** * Transition Connection to CONNECTION_CLOSING. * * No-op if connection is already closing or closed. * * @return ListenableFuture that returns this */ ListenableFuture<? extends C> close(); }