BUG-7222: Improve ClusterSingletonService error handling. 52/51752/1
authorTomas Cere <tcere@cisco.com>
Thu, 9 Feb 2017 13:13:23 +0000 (14:13 +0100)
committerRobert Varga <nite@hq.sk>
Sat, 11 Feb 2017 15:35:08 +0000 (15:35 +0000)
The applications that are managed by singleton service
may throw an unchecked exception while handling the calls from
the service. We also need to handle these so that they don't prevent
other services from being started/stopped.

Change-Id: I711b8c1e8b2fcb8e9a9699ba96fa3b0c2daff594
Signed-off-by: Tomas Cere <tcere@cisco.com>
(cherry picked from commit 55b8b0a9dfe50a20dec1c8e55e1610a4614a51be)

singleton-service/mdsal-singleton-dom-impl/src/main/java/org/opendaylight/mdsal/singleton/dom/impl/ClusterSingletonServiceGroupImpl.java

index 90ffc10e7a78d0977de5287c30301f93db754ab8..145541e6023feeea5bdc828dd499e5d55e24f4fd 100644 (file)
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
 import org.opendaylight.mdsal.eos.common.api.GenericEntity;
 import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipCandidateRegistration;
@@ -116,7 +117,12 @@ final class ClusterSingletonServiceGroupImpl<P extends Path<P>, E extends Generi
             final List<ListenableFuture<Void>> serviceCloseFutureList = new ArrayList<>();
             if (hasOwnership) {
                 for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
-                    serviceCloseFutureList.add(service.closeServiceInstance());
+                    try {
+                        serviceCloseFutureList.add(service.closeServiceInstance());
+                    } catch (final RuntimeException e) {
+                        LOG.warn("Unexpected exception while closing service: {}, resuming with next..",
+                                service.getIdentifier());
+                    }
                 }
                 hasOwnership = false;
             }
@@ -139,7 +145,7 @@ final class ClusterSingletonServiceGroupImpl<P extends Path<P>, E extends Generi
             Verify.verify(!hasOwnership);
             Verify.verify(serviceEntityCandidateReg == null);
             serviceEntityCandidateReg = entityOwnershipService.registerCandidate(serviceEntity);
-        } catch (final Exception e) {
+        } catch (final RuntimeException | InterruptedException | CandidateAlreadyRegisteredException e) {
             LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
             needCloseProviderInstance = true;
             throw new RuntimeException(e);
@@ -164,7 +170,7 @@ final class ClusterSingletonServiceGroupImpl<P extends Path<P>, E extends Generi
             if (hasOwnership) {
                 service.instantiateServiceInstance();
             }
-        } catch (final Exception e) {
+        } catch (final RuntimeException | InterruptedException e) {
             LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
             needCloseProviderInstance = true;
             throw new RuntimeException(e);
@@ -192,7 +198,7 @@ final class ClusterSingletonServiceGroupImpl<P extends Path<P>, E extends Generi
             } else {
                 needCloseProviderInstance = true;
             }
-        } catch (final Exception e) {
+        } catch (final RuntimeException | InterruptedException e) {
             LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
             needCloseProviderInstance = true;
             throw new RuntimeException(e);
@@ -294,7 +300,7 @@ final class ClusterSingletonServiceGroupImpl<P extends Path<P>, E extends Generi
             } else {
                 LOG.debug("Service {} is closed, so don't take leadership", clusterSingletonGroupIdentifier);
             }
-        } catch (final Exception e) {
+        } catch (final RuntimeException | InterruptedException e) {
             LOG.error("Unexpected exception state for service Provider {} in TakeLeadership",
                     clusterSingletonGroupIdentifier, e);
             needCloseProviderInstance = true;
@@ -319,7 +325,12 @@ final class ClusterSingletonServiceGroupImpl<P extends Path<P>, E extends Generi
             if (hasOwnership) {
                 Verify.verify(asyncCloseEntityCandidateReg != null);
                 for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
-                    serviceCloseFutureList.add(service.closeServiceInstance());
+                    try {
+                        serviceCloseFutureList.add(service.closeServiceInstance());
+                    } catch (final RuntimeException e) {
+                        LOG.error("Unexpected exception while closing service: {}, resuming with next..",
+                                service.getIdentifier());
+                    }
                 }
                 hasOwnership = false;
             }
@@ -340,7 +351,7 @@ final class ClusterSingletonServiceGroupImpl<P extends Path<P>, E extends Generi
              * instance has fully closed prior to relinquishing service ownership.
              */
             needReleaseLock = false;
-        } catch (final Exception e) {
+        } catch (final InterruptedException e) {
             LOG.error("Unexpected exception state for service Provider {} in LostLeadership",
                     clusterSingletonGroupIdentifier, e);
             needCloseProviderInstance = true;