Skip to content

Commit

Permalink
Add ListenableFuture to TcpOperations connect methods
Browse files Browse the repository at this point in the history
  • Loading branch information
rstoyanchev committed Oct 23, 2013
1 parent f3ca3c1 commit 2d78a06
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@
import java.net.InetSocketAddress;

import org.springframework.messaging.Message;
import org.springframework.util.Assert;
import org.springframework.util.concurrent.ListenableFuture;

import reactor.core.Environment;
import reactor.core.composable.Composable;
import reactor.core.composable.Deferred;
import reactor.core.composable.Promise;
import reactor.core.composable.Stream;
import reactor.core.composable.spec.Promises;
import reactor.function.Consumer;
import reactor.function.support.SingleUseConsumer;
import reactor.io.Buffer;
import reactor.tcp.Reconnect;
import reactor.tcp.TcpClient;
Expand Down Expand Up @@ -59,27 +64,39 @@ public ReactorNettyTcpClient(String host, int port, Codec<Buffer, Message<P>, Me


@Override
public void connect(TcpConnectionHandler<P> connectionHandler) {
this.connect(connectionHandler, null);
public ListenableFuture<Void> connect(TcpConnectionHandler<P> connectionHandler) {

Promise<TcpConnection<Message<P>, Message<P>>> promise = this.tcpClient.open();
composeConnectionHandling(promise, connectionHandler);

return new AbstractPromiseToListenableFutureAdapter<TcpConnection<Message<P>, Message<P>>, Void>(promise) {
@Override
protected Void adapt(TcpConnection<Message<P>, Message<P>> result) {
return null;
}
};
}

@Override
public void connect(final TcpConnectionHandler<P> connectionHandler,
public ListenableFuture<Void> connect(final TcpConnectionHandler<P> connectionHandler,
final ReconnectStrategy reconnectStrategy) {

Composable<TcpConnection<Message<P>, Message<P>>> composable;
Assert.notNull(reconnectStrategy, "'reconnectStrategy' is required");

if (reconnectStrategy != null) {
composable = this.tcpClient.open(new Reconnect() {
@Override
public Tuple2<InetSocketAddress, Long> reconnect(InetSocketAddress address, int attempt) {
return Tuple.of(address, reconnectStrategy.getTimeToNextAttempt(attempt));
}
});
}
else {
composable = this.tcpClient.open();
}
Stream<TcpConnection<Message<P>, Message<P>>> stream =
this.tcpClient.open(new Reconnect() {
@Override
public Tuple2<InetSocketAddress, Long> reconnect(InetSocketAddress address, int attempt) {
return Tuple.of(address, reconnectStrategy.getTimeToNextAttempt(attempt));
}
});
composeConnectionHandling(stream, connectionHandler);

return new PassThroughPromiseToListenableFutureAdapter<Void>(toPromise(stream));
}

private void composeConnectionHandling(Composable<TcpConnection<Message<P>, Message<P>>> composable,
final TcpConnectionHandler<P> connectionHandler) {

composable.when(Throwable.class, new Consumer<Throwable>() {
@Override
Expand Down Expand Up @@ -108,6 +125,27 @@ public void accept(Message<P> message) {
});
}

private Promise<Void> toPromise(Stream<TcpConnection<Message<P>, Message<P>>> stream) {

final Deferred<Void,Promise<Void>> deferred = Promises.<Void>defer().get();

stream.consume(SingleUseConsumer.once(new Consumer<TcpConnection<Message<P>, Message<P>>>() {
@Override
public void accept(TcpConnection<Message<P>, Message<P>> conn) {
deferred.accept((Void) null);
}
}));

stream.when(Throwable.class, SingleUseConsumer.once(new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) {
deferred.accept(throwable);
}
}));

return deferred.compose();
}

@Override
public ListenableFuture<Void> shutdown() {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public interface TcpConnection<P> {
/**
* Send the given message.
* @param message the message
* @return whether the send succeeded or not
*
* @return a ListenableFuture that can be used to determine when and if the
* message was successfully sent
*/
ListenableFuture<Void> send(Message<P> message);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,28 @@ public interface TcpOperations<P> {
* Open a new connection.
*
* @param connectionHandler a handler to manage the connection
*
* @return a ListenableFuture that can be used to determine when and if the
* connection is successfully established
*/
void connect(TcpConnectionHandler<P> connectionHandler);
ListenableFuture<Void> connect(TcpConnectionHandler<P> connectionHandler);

/**
* Open a new connection and a strategy for reconnecting if the connection fails.
*
* @param connectionHandler a handler to manage the connection
* @param reconnectStrategy a strategy for reconnecting
*
* @return a ListenableFuture that can be used to determine when and if the
* initial connection is successfully established
*/
void connect(TcpConnectionHandler<P> connectionHandler, ReconnectStrategy reconnectStrategy);
ListenableFuture<Void> connect(TcpConnectionHandler<P> connectionHandler, ReconnectStrategy reconnectStrategy);

/**
* Shut down and close any open connections.
*
* @return a ListenableFuture that can be used to determine when and if the
* connection is successfully closed
*/
ListenableFuture<Void> shutdown();

Expand Down

0 comments on commit 2d78a06

Please sign in to comment.