package io.ripc.transport.netty4.tcp;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.ripc.protocol.tcp.TcpConnection;
import io.ripc.transport.netty4.tcp.ChannelToConnectionBridge.ConnectionInputSubscriberEvent;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
public class TcpConnectionImpl<R, W> implements TcpConnection<R, W> {
private final Channel nettyChannel;
public TcpConnectionImpl(Channel nettyChannel) {
this.nettyChannel = nettyChannel;
}
@Override
public Publisher<Void> write(final Publisher<? extends W> data) {
return new Publisher<Void>() {
@Override
public void subscribe(Subscriber<? super Void> s) {
nettyChannel.write(data).addListener(new FutureToSubscriberBridge(s));
}
};
}
@Override
public void subscribe(Subscriber<? super R> s) {
nettyChannel.pipeline().fireUserEventTriggered(new ConnectionInputSubscriberEvent<>(s));
}
private static final Subscription IGNORE_SUBSCRIPTION = new Subscription() {
@Override
public void request(long n) {
//IGNORE
}
@Override
public void cancel() {
//IGNORE
}
};
private static class FutureToSubscriberBridge implements ChannelFutureListener {
private final Subscriber<? super Void> subscriber;
public FutureToSubscriberBridge(Subscriber<? super Void> subscriber) {
this.subscriber = subscriber;
subscriber.onSubscribe(IGNORE_SUBSCRIPTION);
}
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
subscriber.onComplete();
} else {
subscriber.onError(future.cause());
}
}
}
}