PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/protocols/TCP.java

https://gitlab.com/kidaa/incubator-geode
Java | 308 lines | 213 code | 56 blank | 39 comment | 49 complexity | 3ad1057fcf1bfc82c8948751735f9d5f MD5 | raw file
  1. /** Notice of modification as required by the LGPL
  2. * This file was modified by Gemstone Systems Inc. on
  3. * $Date$
  4. **/
  5. // $Id: TCP.java,v 1.31 2005/09/29 12:24:37 belaban Exp $
  6. package com.gemstone.org.jgroups.protocols;
  7. import com.gemstone.org.jgroups.Address;
  8. import com.gemstone.org.jgroups.Event;
  9. import com.gemstone.org.jgroups.Message;
  10. import com.gemstone.org.jgroups.SuspectMember;
  11. import com.gemstone.org.jgroups.blocks.ConnectionTable;
  12. import com.gemstone.org.jgroups.stack.IpAddress;
  13. import com.gemstone.org.jgroups.util.BoundedList;
  14. import com.gemstone.org.jgroups.util.ExternalStrings;
  15. import java.net.InetAddress;
  16. import java.net.UnknownHostException;
  17. import java.util.Properties;
  18. import java.util.Vector;
  19. /**
  20. * TCP based protocol. Creates a server socket, which gives us the local address of this group member. For
  21. * each accept() on the server socket, a new thread is created that listens on the socket.
  22. * For each outgoing message m, if m.dest is in the ougoing hashtable, the associated socket will be reused
  23. * to send message, otherwise a new socket is created and put in the hashtable.
  24. * When a socket connection breaks or a member is removed from the group, the corresponding items in the
  25. * incoming and outgoing hashtables will be removed as well.<br>
  26. * This functionality is in ConnectionTable, which isT used by TCP. TCP sends messages using ct.send() and
  27. * registers with the connection table to receive all incoming messages.
  28. * @author Bela Ban
  29. */
  30. public class TCP extends TP implements ConnectionTable.Receiver {
  31. private ConnectionTable ct=null;
  32. private InetAddress external_addr=null; // the IP address which is broadcast to other group members
  33. private int start_port=7800; // find first available port starting at this port
  34. private int end_port=0; // maximum port to bind to
  35. private long reaper_interval=0; // time in msecs between connection reaps
  36. private long conn_expire_time=0; // max time a conn can be idle before being reaped
  37. /** List the maintains the currently suspected members. This is used so we don't send too many SUSPECT
  38. * events up the stack (one per message !)
  39. */
  40. final BoundedList suspected_mbrs=new BoundedList(20);
  41. /** Should we drop unicast messages to suspected members or not */
  42. boolean skip_suspected_members=true;
  43. /** Use separate send queues for each connection */
  44. boolean use_send_queues=true;
  45. int recv_buf_size=150000;
  46. int send_buf_size=150000;
  47. int sock_conn_timeout=2000; // max time in millis for a socket creation in ConnectionTable
  48. public TCP() {
  49. }
  50. @Override // GemStoneAddition
  51. public String getName() {
  52. return "TCP";
  53. }
  54. public int getOpenConnections() {return ct.getNumConnections();}
  55. public InetAddress getBindAddr() {return bind_addr;}
  56. public void setBindAddr(InetAddress bind_addr) {this.bind_addr=bind_addr;}
  57. public int getStartPort() {return start_port;}
  58. public void setStartPort(int start_port) {this.start_port=start_port;}
  59. public int getEndPort() {return end_port;}
  60. public void setEndPort(int end_port) {this.end_port=end_port;}
  61. public long getReaperInterval() {return reaper_interval;}
  62. public void setReaperInterval(long reaper_interval) {this.reaper_interval=reaper_interval;}
  63. public long getConnExpireTime() {return conn_expire_time;}
  64. public void setConnExpireTime(long conn_expire_time) {this.conn_expire_time=conn_expire_time;}
  65. @Override // GemStoneAddition
  66. public boolean isLoopback() {return loopback;}
  67. @Override // GemStoneAddition
  68. public void setLoopback(boolean loopback) {this.loopback=loopback;}
  69. public String printConnections() {return ct.toString();}
  70. /** Setup the Protocol instance acording to the configuration string */
  71. @Override // GemStoneAddition
  72. public boolean setProperties(Properties props) {
  73. String str;
  74. super.setProperties(props);
  75. str=props.getProperty("start_port");
  76. if(str != null) {
  77. start_port=Integer.parseInt(str);
  78. props.remove("start_port");
  79. }
  80. str=props.getProperty("end_port");
  81. if(str != null) {
  82. end_port=Integer.parseInt(str);
  83. props.remove("end_port");
  84. }
  85. str=props.getProperty("external_addr");
  86. if(str != null) {
  87. try {
  88. external_addr=InetAddress.getByName(str);
  89. }
  90. catch(UnknownHostException unknown) {
  91. if(log.isFatalEnabled()) log.fatal("(external_addr): host " + str + " not known");
  92. return false;
  93. }
  94. props.remove("external_addr");
  95. }
  96. str=props.getProperty("reaper_interval");
  97. if(str != null) {
  98. reaper_interval=Long.parseLong(str);
  99. props.remove("reaper_interval");
  100. }
  101. str=props.getProperty("conn_expire_time");
  102. if(str != null) {
  103. conn_expire_time=Long.parseLong(str);
  104. props.remove("conn_expire_time");
  105. }
  106. str=props.getProperty("sock_conn_timeout");
  107. if(str != null) {
  108. sock_conn_timeout=Integer.parseInt(str);
  109. props.remove("sock_conn_timeout");
  110. }
  111. str=props.getProperty("recv_buf_size");
  112. if(str != null) {
  113. recv_buf_size=Integer.parseInt(str);
  114. props.remove("recv_buf_size");
  115. }
  116. str=props.getProperty("send_buf_size");
  117. if(str != null) {
  118. send_buf_size=Integer.parseInt(str);
  119. props.remove("send_buf_size");
  120. }
  121. str=props.getProperty("skip_suspected_members");
  122. if(str != null) {
  123. skip_suspected_members=Boolean.valueOf(str).booleanValue();
  124. props.remove("skip_suspected_members");
  125. }
  126. str=props.getProperty("use_send_queues");
  127. if(str != null) {
  128. use_send_queues=Boolean.valueOf(str).booleanValue();
  129. props.remove("use_send_queues");
  130. }
  131. if(props.size() > 0) {
  132. log.error(ExternalStrings.TCP_THE_FOLLOWING_PROPERTIES_ARE_NOT_RECOGNIZED__0, props);
  133. return false;
  134. }
  135. return true;
  136. }
  137. @Override // GemStoneAddition
  138. public void start() throws Exception {
  139. ct=getConnectionTable(reaper_interval,conn_expire_time,bind_addr,external_addr,start_port,end_port);
  140. ct.setUseSendQueues(use_send_queues);
  141. // ct.addConnectionListener(this);
  142. ct.setReceiveBufferSize(recv_buf_size);
  143. ct.setSendBufferSize(send_buf_size);
  144. ct.setSocketConnectionTimeout(sock_conn_timeout);
  145. local_addr=ct.getLocalAddress();
  146. if(additional_data != null && local_addr instanceof IpAddress)
  147. ((IpAddress)local_addr).setAdditionalData(additional_data);
  148. super.start();
  149. }
  150. @Override // GemStoneAddition
  151. public void stop() {
  152. ct.stop();
  153. super.stop();
  154. }
  155. @Override // GemStoneAddition
  156. protected void handleDownEvent(Event evt) {
  157. super.handleDownEvent(evt);
  158. if(evt.getType() == Event.VIEW_CHANGE) {
  159. suspected_mbrs.removeAll();
  160. }
  161. else if(evt.getType() == Event.UNSUSPECT) {
  162. suspected_mbrs.removeElement(evt.getArg());
  163. }
  164. }
  165. /**
  166. * @param reaperInterval
  167. * @param connExpireTime
  168. * @param bindAddress
  169. * @param startPort
  170. * @throws Exception
  171. * @return ConnectionTable
  172. * Sub classes overrides this method to initialize a different version of
  173. * ConnectionTable.
  174. */
  175. protected ConnectionTable getConnectionTable(long reaperInterval, long connExpireTime, InetAddress bindAddress,
  176. InetAddress externalAddress, int startPort, int endPort) throws Exception {
  177. ConnectionTable cTable;
  178. if(reaperInterval == 0 && connExpireTime == 0) {
  179. cTable=new ConnectionTable(this, bindAddress, externalAddress, startPort, endPort);
  180. }
  181. else {
  182. if(reaperInterval == 0) {
  183. reaperInterval=5000;
  184. if(warn) log.warn("reaper_interval was 0, set it to " + reaperInterval);
  185. }
  186. if(connExpireTime == 0) {
  187. connExpireTime=1000 * 60 * 5;
  188. if(warn) log.warn("conn_expire_time was 0, set it to " + connExpireTime);
  189. }
  190. cTable=new ConnectionTable(this, bindAddress, externalAddress, startPort, endPort,
  191. reaperInterval, connExpireTime);
  192. }
  193. return cTable;
  194. }
  195. /** ConnectionTable.Receiver interface */
  196. public void receive(Address sender, byte[] data, int offset, int length) {
  197. super.receive(local_addr, sender, data, offset, length);
  198. }
  199. @Override // GemStoneAddition
  200. public void sendToAllMembers(byte[] data, int offset, int length) throws Exception {
  201. Address dest;
  202. Vector mbrs=(Vector)members.clone();
  203. for(int i=0; i < mbrs.size(); i++) {
  204. dest=(Address)mbrs.elementAt(i);
  205. sendToSingleMember(dest, false, data, offset, length);
  206. }
  207. }
  208. @Override // GemStoneAddition
  209. public void sendToSingleMember(Address dest, boolean isJoinResponse/*temporary change - do not commit*/, byte[] data, int offset, int length) throws Exception {
  210. if(trace) log.trace("dest=" + dest + " (" + data.length + " bytes)");
  211. if(skip_suspected_members) {
  212. if(suspected_mbrs.contains(dest)) {
  213. if(trace)
  214. log.trace("will not send unicast message to " + dest + " as it is currently suspected");
  215. return;
  216. }
  217. }
  218. // if(dest.equals(local_addr)) {
  219. // if(!loopback) // if loopback, we discard the message (was already looped back)
  220. // receive(dest, data, offset, length); // else we loop it back here
  221. // return;
  222. // }
  223. try {
  224. ct.send(dest, data, offset, length);
  225. }
  226. catch(Exception e) {
  227. if(members.contains(dest)) {
  228. if(!suspected_mbrs.contains(dest)) {
  229. suspected_mbrs.add(dest);
  230. passUp(new Event(Event.SUSPECT, new SuspectMember(local_addr, dest))); // GemStoneAddition SuspectMember
  231. }
  232. }
  233. }
  234. }
  235. @Override // GemStoneAddition
  236. public String getInfo() {
  237. StringBuffer sb=new StringBuffer();
  238. sb.append("connections: ").append(printConnections()).append("\n");
  239. return sb.toString();
  240. }
  241. @Override // GemStoneAddition
  242. public void postUnmarshalling(Message msg, Address dest, Address src, boolean multicast) {
  243. if(multicast)
  244. msg.setDest(null);
  245. else
  246. msg.setDest(dest);
  247. }
  248. @Override // GemStoneAddition
  249. public void postUnmarshallingList(Message msg, Address dest, boolean multicast) {
  250. postUnmarshalling(msg, dest, null, multicast);
  251. }
  252. }