PageRenderTime 26ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/MsgStreamerList.java

https://gitlab.com/kidaa/incubator-geode
Java | 160 lines | 100 code | 12 blank | 48 comment | 25 complexity | 3227490041e04a961cf814adec6a0f9f MD5 | raw file
  1. /*=========================================================================
  2. * Copyright (c) 2009-2014 Pivotal Software, Inc. All Rights Reserved. This product
  3. * is protected by U.S. and international copyright and intellectual
  4. * property laws. Pivotal products are covered by one or more patents listed
  5. * at http://www.pivotal.io/patents.
  6. *=========================================================================
  7. */
  8. package com.gemstone.gemfire.internal.tcp;
  9. import java.io.IOException;
  10. import java.util.Collections;
  11. import java.util.List;
  12. import org.apache.logging.log4j.Logger;
  13. import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
  14. import com.gemstone.gemfire.internal.logging.LogService;
  15. /**
  16. * Encapsulates a set of {@link MsgStreamer}s and {@link VersionedMsgStreamer}s
  17. * requiring possibly different serializations for different versions of
  18. * product.
  19. *
  20. * @author swale
  21. * @since 7.1
  22. */
  23. public final class MsgStreamerList implements BaseMsgStreamer {
  24. private static final Logger logger = LogService.getLogger();
  25. /**
  26. * List of {@link MsgStreamer}s encapsulated by this MsgStreamerList.
  27. */
  28. private final List<MsgStreamer> streamers;
  29. MsgStreamerList(List<MsgStreamer> streamers) {
  30. this.streamers = streamers;
  31. }
  32. /**
  33. * {@inheritDoc}
  34. */
  35. @Override
  36. public void reserveConnections(long startTime, long ackTimeout,
  37. long ackSDTimeout) {
  38. for (MsgStreamer streamer : this.streamers) {
  39. streamer.reserveConnections(startTime, ackTimeout, ackSDTimeout);
  40. }
  41. }
  42. /**
  43. * {@inheritDoc}
  44. */
  45. @Override
  46. public int writeMessage() throws IOException {
  47. int result = 0;
  48. RuntimeException ex = null;
  49. IOException ioex = null;
  50. for (MsgStreamer streamer : this.streamers) {
  51. if (ex != null) {
  52. streamer.release();
  53. // TODO: shouldn't we call continue here?
  54. // It seems wrong to call writeMessage on a streamer we have just released.
  55. // But why do we call release on a streamer when we had an exception on one
  56. // of the previous streamer?
  57. // release clears the direct bb and returns it to the pool but leaves
  58. // it has the "buffer". THen we call writeMessage and it will use "buffer"
  59. // that has also been returned to the pool.
  60. // I think we only have a MsgStreamerList when a DS has a mix of versions
  61. // which usually is just during a rolling upgrade so that might be why we
  62. // haven't noticed this causing a bug.
  63. }
  64. try {
  65. result += streamer.writeMessage();
  66. // if there is an exception we need to finish the
  67. // loop and release the other streamer's buffers
  68. } catch (RuntimeException e) {
  69. ex = e;
  70. } catch (IOException e) {
  71. ioex = e;
  72. }
  73. }
  74. if (ex != null) {
  75. throw ex;
  76. }
  77. if (ioex != null) {
  78. throw ioex;
  79. }
  80. return result;
  81. }
  82. /**
  83. * {@inheritDoc}
  84. */
  85. @SuppressWarnings("unchecked")
  86. @Override
  87. public List<?> getSentConnections() {
  88. List<Object> sentCons = Collections.emptyList();
  89. for (MsgStreamer streamer : this.streamers) {
  90. if (sentCons.size() == 0) {
  91. sentCons = (List<Object>)streamer.getSentConnections();
  92. }
  93. else {
  94. sentCons.addAll(streamer.getSentConnections());
  95. }
  96. }
  97. return sentCons;
  98. }
  99. /**
  100. * {@inheritDoc}
  101. */
  102. @Override
  103. public ConnectExceptions getConnectExceptions() {
  104. ConnectExceptions ce = null;
  105. for (MsgStreamer streamer : this.streamers) {
  106. if (ce == null) {
  107. ce = streamer.getConnectExceptions();
  108. }
  109. else {
  110. // loop through all failures and add to base ConnectionException
  111. ConnectExceptions e = streamer.getConnectExceptions();
  112. if (e != null) {
  113. List<?> members = e.getMembers();
  114. List<?> exs = e.getCauses();
  115. for (int i = 0; i < exs.size(); i++) {
  116. ce.addFailure((InternalDistributedMember)members.get(i),
  117. (Throwable)exs.get(i));
  118. }
  119. }
  120. }
  121. }
  122. return ce;
  123. }
  124. /**
  125. * {@inheritDoc}
  126. */
  127. @Override
  128. public void close() throws IOException {
  129. // only throw the first exception and try to close all
  130. IOException ex = null;
  131. for (MsgStreamer m : this.streamers) {
  132. try {
  133. m.close();
  134. } catch (IOException e) {
  135. if (ex == null) {
  136. ex = e;
  137. }
  138. else {
  139. // log the exception and move on to close others
  140. logger.fatal("Unknown error closing streamer: {}", e.getMessage(), e);
  141. }
  142. }
  143. }
  144. if (ex != null) {
  145. throw ex;
  146. }
  147. }
  148. }