两个连接请求发出后,生成ClientConnectionId对象,只要两个ClientConnectionId对象的hashcode相同,就视为一个同一个连接,从而复用ClientConnection
publicRPCInvoker(Class《?extendsVersionedProtocol》protocol,
InetSocketAddress address, UserGroupInformation ticket,
Configuration conf, SocketFactory factory,
intrpcTimeout)throwsIOException{
this.remoteId=ClientConnectionId.getConnectionId(address,protocol,
ticket, rpcTimeout, conf);
this.client= RPC.CLIENTS.getClient(conf,factory);
}
privateClientConnectiongetConnection(ClientConnectionId remoteId,
ClientCall call)
throwsIOException,InterruptedException {
if (!running.get()){
thrownewIOException("Theclient is stopped");
}
ClientConnection connection;
do{
synchronized(connections){
connection =connections.get(remoteId);
if(connection== null){
connection = newClientConnection(remoteId,this);
connections.put(remoteId,connection);
}
}
} while(!connection.addCall(call));
connection.setupIOstreams();
returnconnection;
}
publicclassClientConnectionId{
InetSocketAddress address;
UserGroupInformation ticket;
Class<?> protocol;
staticfinalintPRIME=16777619;
intrpcTimeout;
String serverPrincipal;
intmaxIdleTime;//connectionswill be culled if it was idle for
//maxIdleTimemsecs
intmaxRetries;//the max.no. of retries for socket connections
booleantcpNoDelay;// if T thendisable Nagle's Algorithm
intpingInterval;// how oftensends ping to the server in msecs
ClientConnectionId(InetSocketAddress address,Class<?> protocol,
UserGroupInformation ticket, intrpcTimeout,
String serverPrincipal, intmaxIdleTime,
intmaxRetries,booleantcpNoDelay,
intpingInterval){
this.protocol=protocol;
this.address=address;
this.ticket=ticket;
this.rpcTimeout=rpcTimeout;
this.serverPrincipal=serverPrincipal;
this.maxIdleTime=maxIdleTime;
this.maxRetries=maxRetries;
this.tcpNoDelay=tcpNoDelay;
this.pingInterval=pingInterval;
}
staticClientConnectionIdgetConnectionId(InetSocketAddress addr,
Class<?> protocol,UserGroupInformation ticket, intrpcTimeout,
Configuration conf) throwsIOException{
returnnewClientConnectionId(addr,protocol, ticket,
rpcTimeout, null,
conf.getInt("ipc.client.connection.maxidletime",10000), //10s
conf.getInt("ipc.client.connect.max.retries",10),
conf.getBoolean("ipc.client.tcpnodelay",false),
Client.getPingInterval(conf));
}
staticbooleanisEqual(Object a, Objectb) {
returna ==null? b ==null:a.equals(b);
}
@Override
publicbooleanequals(Objectobj) {
if(obj== this){
returntrue;
}
if(objinstanceofClientConnectionId){
ClientConnectionId that = (ClientConnectionId) obj;
returnisEqual(this.address,that.address)
&& this.maxIdleTime==that.maxIdleTime
&& this.maxRetries==that.maxRetries
&& this.pingInterval==that.pingInterval
&& isEqual(this.protocol,that.protocol)
&& this.rpcTimeout==that.rpcTimeout
&& isEqual(this.serverPrincipal,that.serverPrincipal)
&& this.tcpNoDelay==that.tcpNoDelay
&&isEqual(this.ticket,that.ticket);
}
returnfalse;
}
@Override
publicinthashCode() {
intresult =1;
result = PRIME* result +((address==null)? 0 : address.hashCode());
result = PRIME* result+ maxIdleTime;
result = PRIME* result+ maxRetries;
result = PRIME* result+ pingInterval;
result = PRIME* result +((protocol==null)? 0 : protocol.hashCode());
result = PRIME*rpcTimeout;
result = PRIME*result
+ ((serverPrincipal==null)? 0 : serverPrincipal.hashCode());
result = PRIME* result +(tcpNoDelay? 1231 :1237);
result = PRIME* result +((ticket==null)? 0 : ticket.hashCode());
returnresult;
}
}