Description
This issue is for discussing API for a TCP client.
Intention
To define how TCP must be modeled from a client point of view, using reactive-streams-jvm SPI.
What it is?
An abstraction over:
- How to create a TCP connection?
- How to write to a TCP connection?
- How to read from a TCP connection?
What it is not?
In general it should not try to arbitrate different standards across different networking libraries. A few examples of that being:
- Define what are the ways to configure a connection, eg: connect timeout, socket backlog, etc. Netty has Channel Options, xnio has Options.
- Define the stages of a connect process i.e how should a physical connection be created.
- Define how does data get read or written over a physical connection.
Extension points
Although, this API does not intend to arbitrate different standards across different networking libraries, we should not impede the implementations from implementing them effectively. So, as a part of this exercise, it will be good to identify various higher level requirements from such a client and see that our design is not impeding those implementations. A few things that may be of value to consider are:
- Could there be connection configurations per connection attempt?
- How would a client use a target server pool by load balancing across these hosts?
- How would a client reconnect on connection failures? Considering that reconnects should not happen on the same target server.
Implementations
It would be good to discuss how an implementation could be using this API?
If we happen to model our TCPClient as:
public interface TcpClient<R, W> {
Publisher<TcpConnection<R, W>> connect(SocketAddress remoteAddress);
}
would a Netty implementation look like:
public class NettyTcpClient<R, W> implements TcpClient<R, W> {
Publisher<TcpConnection<R, W>> connect(SocketAddress remoteAddress);
}
or would this be hidden around another interface like:
public interface NettyTcpClient<R, W> extends TcpClient<R, W> {
// Other methods
}
Furthermore, how would an implementation of reactive streams like RxJava layer on top of it?
Would it be like:
public interface RxJavaTcpClient<R, W> {
Observable<TcpConnection<R, W>> connect(SocketAddress remoteAddress);
}
or
RxTcpClient.from(TcpClient<R, W> client);
which gives an adapter over any TcpClient
implementation.
The intention of these questions is to be aware of usage of this API.