2121import java .util .Properties ;
2222import java .util .concurrent .CountDownLatch ;
2323import java .util .concurrent .TimeUnit ;
24+ import java .util .concurrent .atomic .AtomicBoolean ;
2425
2526import io .grpc .ManagedChannel ;
2627import io .grpc .ManagedChannelBuilder ;
3536import org .hyperledger .fabric .protos .peer .PeerEvents .DeliverResponse ;
3637import org .hyperledger .fabric .sdk .Channel .PeerOptions ;
3738import org .hyperledger .fabric .sdk .exception .CryptoException ;
39+ import org .hyperledger .fabric .sdk .exception .PeerEventingServiceException ;
3840import org .hyperledger .fabric .sdk .exception .TransactionException ;
3941import org .hyperledger .fabric .sdk .helper .Config ;
4042import org .hyperledger .fabric .sdk .transaction .TransactionContext ;
@@ -146,7 +148,7 @@ synchronized void shutdown(boolean force) {
146148 }
147149 }
148150 }
149- peer = null ;
151+
150152 channelEventQue = null ;
151153
152154 }
@@ -169,6 +171,8 @@ void connectEnvelope(Envelope envelope) throws TransactionException {
169171 return ;
170172 }
171173
174+ final AtomicBoolean retry = new AtomicBoolean (true ); // make sure we only retry connection once for each connection attempt.
175+
172176 ManagedChannel lmanagedChannel = managedChannel ;
173177
174178 if (lmanagedChannel == null || lmanagedChannel .isTerminated () || lmanagedChannel .isShutdown ()) {
@@ -208,8 +212,16 @@ public void onNext(DeliverResponse resp) {
208212 peer .resetReconnectCount ();
209213 } else {
210214
211- throwableList .add (new TransactionException (format ("Channel %s peer %s Status returned failure code %d (%s) during peer service event registration" ,
212- channelName , peer .getName (), resp .getStatusValue (), resp .getStatus ().name ())));
215+ final long rec = peer .getReconnectCount ();
216+
217+ PeerEventingServiceException peerEventingServiceException = new PeerEventingServiceException (format ("Channel %s peer %s attempts %s Status returned failure code %d (%s) during peer service event registration" ,
218+ channelName , peer .getName (), rec , resp .getStatusValue (), resp .getStatus ().name ()));
219+ peerEventingServiceException .setResponse (resp );
220+ if (rec % 10 == 0 ) {
221+ logger .warn (peerEventingServiceException .getMessage ());
222+ }
223+
224+ throwableList .add (peerEventingServiceException );
213225 }
214226
215227 } else if (typeCase == FILTERED_BLOCK || typeCase == BLOCK ) {
@@ -224,10 +236,8 @@ public void onNext(DeliverResponse resp) {
224236 peer .setLastConnectTime (System .currentTimeMillis ());
225237 long reconnectCount = peer .getReconnectCount ();
226238 if (reconnectCount > 1 ) {
227-
228239 logger .info (format ("Peer eventing service reconnected after %d attempts on channel %s, peer %s, url %s" ,
229240 reconnectCount , channelName , name , url ));
230-
231241 }
232242 peer .resetReconnectCount ();
233243
@@ -239,8 +249,11 @@ public void onNext(DeliverResponse resp) {
239249 logger .error (format ("Channel %s peer %s got event block with unknown type: %s, %d" ,
240250 channelName , peer .getName (), typeCase .name (), typeCase .getNumber ()));
241251
242- throwableList .add (new TransactionException (format ("Channel %s peer %s Status got unknown type %s, %d" ,
243- channelName , peer .getName (), typeCase .name (), typeCase .getNumber ())));
252+ PeerEventingServiceException peerEventingServiceException = new PeerEventingServiceException (format ("Channel %s peer %s got event block with unknown type: %s, %d" ,
253+ channelName , peer .getName (), typeCase .name (), typeCase .getNumber ()));
254+ peerEventingServiceException .setResponse (resp );
255+
256+ throwableList .add (peerEventingServiceException );
244257
245258 }
246259 finishLatch .countDown ();
@@ -251,7 +264,12 @@ public void onNext(DeliverResponse resp) {
251264 public void onError (Throwable t ) {
252265 ManagedChannel llmanagedChannel = managedChannel ;
253266 if (llmanagedChannel != null ) {
254- llmanagedChannel .shutdownNow ();
267+ try {
268+ llmanagedChannel .shutdownNow ();
269+ } catch (Exception e ) {
270+ logger .warn (format ("Received error on peer eventing service on channel %s, peer %s, url %s, attempts %d. %s shut down of grpc channel." ,
271+ channelName , name , url , peer == null ? -1 : peer .getReconnectCount (), e .getMessage ()), e );
272+ }
255273 managedChannel = null ;
256274 }
257275 if (!shutdown ) {
@@ -266,7 +284,9 @@ public void onError(Throwable t) {
266284
267285 }
268286
269- peer .reconnectPeerEventServiceClient (PeerEventServiceClient .this , t );
287+ if (retry .getAndSet (false )) {
288+ peer .reconnectPeerEventServiceClient (PeerEventServiceClient .this , t );
289+ }
270290
271291 }
272292 finishLatch .countDown ();
@@ -288,8 +308,9 @@ public void onCompleted() {
288308
289309 // try {
290310 if (!finishLatch .await (peerEventRegistrationWaitTimeMilliSecs , TimeUnit .MILLISECONDS )) {
291- TransactionException ex = new TransactionException (format (
311+ PeerEventingServiceException ex = new PeerEventingServiceException (format (
292312 "Channel %s connect time exceeded for peer eventing service %s, timed out at %d ms." , channelName , name , peerEventRegistrationWaitTimeMilliSecs ));
313+ ex .setTimedOut (peerEventRegistrationWaitTimeMilliSecs );
293314 throwableList .add (0 , ex );
294315
295316 }
@@ -302,7 +323,9 @@ public void onCompleted() {
302323 managedChannel = null ;
303324 }
304325 Throwable throwable = throwableList .get (0 );
305- peer .reconnectPeerEventServiceClient (this , throwable );
326+ if (retry .getAndSet (false )) {
327+ peer .reconnectPeerEventServiceClient (this , throwable );
328+ }
306329
307330 }
308331
@@ -314,7 +337,9 @@ public void onCompleted() {
314337 }
315338 logger .error (e ); // not likely
316339
317- peer .reconnectPeerEventServiceClient (this , e );
340+ if (retry .getAndSet (false )) {
341+ peer .reconnectPeerEventServiceClient (this , e );
342+ }
318343
319344 } finally {
320345 if (null != nso ) {
0 commit comments