package edu.uw.zookeeper.net.intravm; import java.net.SocketAddress; import java.nio.channels.ClosedChannelException; import java.util.concurrent.Executor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.google.common.collect.Queues; import edu.uw.zookeeper.common.Eventful; import edu.uw.zookeeper.common.Stateful; import edu.uw.zookeeper.net.Connection; public final class IntraVmEndpoint<I,O> extends AbstractIntraVmEndpoint<I,O,I,O> implements Stateful<Connection.State>, Eventful<Connection.Listener<? super O>>, Executor { public static <I,O> IntraVmEndpoint<I,O> newInstance( SocketAddress address, Executor executor) { Logger logger = LogManager.getLogger(IntraVmEndpoint.class); return new IntraVmEndpoint<I,O>( address, executor, logger, IntraVmPublisher.<O>defaults(executor, logger)); } private final EndpointReader reader; private final EndpointWriter writer; protected IntraVmEndpoint( SocketAddress address, Executor executor, Logger logger, IntraVmPublisher<O> publisher) { super(address, executor, logger, publisher); this.reader = new EndpointReader(); this.writer = new EndpointWriter(); } @Override public EndpointReader reader() { return reader; } @Override public EndpointWriter writer() { return writer; } public final class EndpointWriter extends AbstractEndpointWriter { protected EndpointWriter() { super(Queues.<EndpointWrite<? extends I,I>>newLinkedBlockingDeque()); } @Override protected boolean apply(EndpointWrite<? extends I, I> input) throws Exception { if (input.remote().reader().send(input.message())) { input.run(); return true; } else { Exception e = new ClosedChannelException(); input.setException(e); throw e; } } } public final class EndpointReader extends AbstractEndpointReader { protected EndpointReader() { super(Queues.<O>newLinkedBlockingDeque()); } @Override protected boolean apply(O input) throws Exception { return publisher.send(input); } } }