X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=singleton-service%2Fmdsal-singleton-dom-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fsingleton%2Fdom%2Fimpl%2FClusterSingletonServiceGroupImpl.java;h=90ffc10e7a78d0977de5287c30301f93db754ab8;hb=62a591d105563555955efeeddb4f16af38529d57;hp=af18888ef24dddd43799754d35041df6cf276887;hpb=8216dbb9b22b70155a583e7d5444c0f6da78b0a1;p=mdsal.git diff --git a/singleton-service/mdsal-singleton-dom-impl/src/main/java/org/opendaylight/mdsal/singleton/dom/impl/ClusterSingletonServiceGroupImpl.java b/singleton-service/mdsal-singleton-dom-impl/src/main/java/org/opendaylight/mdsal/singleton/dom/impl/ClusterSingletonServiceGroupImpl.java index af18888ef2..90ffc10e7a 100644 --- a/singleton-service/mdsal-singleton-dom-impl/src/main/java/org/opendaylight/mdsal/singleton/dom/impl/ClusterSingletonServiceGroupImpl.java +++ b/singleton-service/mdsal-singleton-dom-impl/src/main/java/org/opendaylight/mdsal/singleton/dom/impl/ClusterSingletonServiceGroupImpl.java @@ -56,12 +56,18 @@ final class ClusterSingletonServiceGroupImpl
, E extends Generi private final S entityOwnershipService; private final String clusterSingletonGroupIdentifier; - private final Semaphore clusterLock = new Semaphore(1); + private final Semaphore clusterLock = new Semaphore(1, true); /* Entity instances */ private final E serviceEntity; private final E doubleCandidateEntity; + // TODO :it needs to rewrite for StateMachine (INITIALIZED, TRY_TO_TAKE_LEADERSHIP, LEADER, FOLLOWER, TERMINATED) + // INITIALIZED : we have registered baseCandidate and we are waiting for first EOS response (!do we really need it?) + // FOLLOWER : baseCandidate is registered correctly + // TRY_TO_TAKE_LEADERSHIP : guardCandidate is registered correctly + // LEADER : both candidate have mastership from EOS + // TERMINATED : service go down @GuardedBy("clusterLock") private boolean hasOwnership = false; @GuardedBy("clusterLock") @@ -98,9 +104,10 @@ final class ClusterSingletonServiceGroupImpl
, E extends Generi
boolean needReleaseLock = false;
final ListenableFuture , E extends Generi
for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
serviceCloseFutureList.add(service.closeServiceInstance());
}
+ hasOwnership = false;
}
destroyFuture = Futures.allAsList(serviceCloseFutureList);
final Semaphore finalRelease = needReleaseLock ? clusterLock : null;
- Futures.addCallback(destroyFuture, newAsyncCloseCallback(finalRelease));
+ Futures.addCallback(destroyFuture, newAsyncCloseCallback(finalRelease, true));
}
return destroyFuture;
}
@@ -134,6 +142,7 @@ final class ClusterSingletonServiceGroupImpl , E extends Generi
} catch (final Exception e) {
LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
needCloseProviderInstance = true;
+ throw new RuntimeException(e);
} finally {
closeResources(needReleaseLock, needCloseProviderInstance);
}
@@ -158,6 +167,7 @@ final class ClusterSingletonServiceGroupImpl , E extends Generi
} catch (final Exception e) {
LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
needCloseProviderInstance = true;
+ throw new RuntimeException(e);
} finally {
closeResources(needReleaseLock, needCloseProviderInstance);
}
@@ -173,24 +183,27 @@ final class ClusterSingletonServiceGroupImpl , E extends Generi
try {
clusterLock.acquire();
needReleaseLock = true;
- serviceGroup.remove(service);
- if (hasOwnership) {
- service.closeServiceInstance();
+ if (serviceGroup.size() > 1) {
+ if (hasOwnership) {
+ service.closeServiceInstance();
+ }
+ serviceGroup.remove(service);
+ LOG.debug("Service {} was removed from group.", service.getIdentifier().getValue());
+ } else {
+ needCloseProviderInstance = true;
}
} catch (final Exception e) {
LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
needCloseProviderInstance = true;
+ throw new RuntimeException(e);
} finally {
closeResources(needReleaseLock, needCloseProviderInstance);
- if (serviceGroup.isEmpty()) {
- this.closeClusterSingletonGroup();
- }
}
}
@Override
- public final void ownershipChanged(final C ownershipChange) {
- LOG.debug("Ownership change {} for ClusterSingletonServiceGrou {}", ownershipChange,
+ public void ownershipChanged(final C ownershipChange) {
+ LOG.debug("Ownership change {} for ClusterSingletonServiceGroup {}", ownershipChange,
clusterSingletonGroupIdentifier);
try {
if (ownershipChange.inJeopardy()) {
@@ -222,15 +235,6 @@ final class ClusterSingletonServiceGroupImpl , E extends Generi
* SLAVE to MASTER : ownershipChange.getState().isOwner() && !ownershipChange.getState().wasOwner()
*/
takeOwnership();
- } else if (EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER.equals(ownershipChange.getState())
- || EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NO_OWNER
- .equals(ownershipChange.getState())) {
- /*
- * MASTER to SLAVE : !ownershipChange.getState().isOwner() && ownershipChange.getState().wasOwner()
- */
- LOG.warn("Unexpected lost doubleCandidate {} leadership. Close service instance {}",
- doubleCandidateEntity, clusterSingletonGroupIdentifier);
- lostOwnership();
} else {
/* Not needed notifications */
LOG.debug("Not processed doubleCandidate OwnershipChange {} in service Provider {}",
@@ -256,9 +260,12 @@ final class ClusterSingletonServiceGroupImpl , E extends Generi
try {
clusterLock.acquire();
needReleaseLock = true;
- Verify.verify(serviceEntityCandidateReg != null);
- Verify.verify(asyncCloseEntityCandidateReg == null);
- asyncCloseEntityCandidateReg = entityOwnershipService.registerCandidate(doubleCandidateEntity);
+ if (serviceEntityCandidateReg != null) {
+ Verify.verify(asyncCloseEntityCandidateReg == null);
+ asyncCloseEntityCandidateReg = entityOwnershipService.registerCandidate(doubleCandidateEntity);
+ } else {
+ LOG.debug("Service {} is closed, so don't to tryTakeLeadership", clusterSingletonGroupIdentifier);
+ }
} catch (final Exception e) {
LOG.error("Unexpected exception state for service Provider {} in TryToTakeLeadership",
clusterSingletonGroupIdentifier, e);
@@ -278,12 +285,15 @@ final class ClusterSingletonServiceGroupImpl , E extends Generi
try {
clusterLock.acquire();
needReleaseLock = true;
- Verify.verify(serviceEntityCandidateReg != null);
- Verify.verify(asyncCloseEntityCandidateReg != null);
- for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
- service.instantiateServiceInstance();
+ if (serviceEntityCandidateReg != null) {
+ Verify.verify(asyncCloseEntityCandidateReg != null);
+ for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
+ service.instantiateServiceInstance();
+ }
+ hasOwnership = true;
+ } else {
+ LOG.debug("Service {} is closed, so don't take leadership", clusterSingletonGroupIdentifier);
}
- hasOwnership = true;
} catch (final Exception e) {
LOG.error("Unexpected exception state for service Provider {} in TakeLeadership",
clusterSingletonGroupIdentifier, e);
@@ -305,17 +315,23 @@ final class ClusterSingletonServiceGroupImpl , E extends Generi
try {
clusterLock.acquire();
needReleaseLock = true;
- Verify.verify(serviceEntityCandidateReg != null);
final List , E extends Generi
/*
* Help method for finalization every acquired functionality
*/
+ @GuardedBy("clusterLock")
private void closeResources(final boolean needReleaseLock, final boolean needCloseProvider) {
- if (needReleaseLock) {
- clusterLock.release();
- }
if (needCloseProvider) {
- final ListenableFuture , E extends Generi
asyncCloseEntityCandidateReg.close();
asyncCloseEntityCandidateReg = null;
}
+ if (isInCloseProcess) {
+ allServiceGroups.remove(clusterSingletonGroupIdentifier, this);
+ }
if (semaphore != null) {
semaphore.release();
}
- allServiceGroups.remove(clusterSingletonGroupIdentifier, this);
};
return new FutureCallback> destroyFuture;
try {
- needReleaseLock = clusterLock.tryAcquire(10, TimeUnit.SECONDS);
+ needReleaseLock = clusterLock.tryAcquire(1, TimeUnit.SECONDS);
} catch (final Exception e) {
- LOG.warn("Unexpected Exception for service Provider {} in closing phase.", clusterSingletonGroupIdentifier, e);
+ LOG.warn("Unexpected Exception for service Provider {} in closing phase.", clusterSingletonGroupIdentifier,
+ e);
} finally {
if (serviceEntityCandidateReg != null) {
serviceEntityCandidateReg.close();
@@ -111,10 +118,11 @@ final class ClusterSingletonServiceGroupImpl
> destroyFuture = Futures.allAsList(serviceCloseFutureList);
- Futures.addCallback(destroyFuture, newAsyncCloseCallback(clusterLock));
+ if (serviceEntityCandidateReg != null) {
+ // we don't want to remove this instance from map
+ Futures.addCallback(destroyFuture, newAsyncCloseCallback(clusterLock, false));
+ } else {
+ // we have to remove this ClusterSingletonServiceGroup instance from map
+ Futures.addCallback(destroyFuture, newAsyncCloseCallback(clusterLock, true));
+ }
/*
* We wish to stop all possible EOS activities before we don't close
* a close candidate registration that acts as a guard. So we don't want
@@ -336,46 +352,33 @@ final class ClusterSingletonServiceGroupImpl
> closeFutureList = this.closeClusterSingletonGroup();
- Futures.addCallback(closeFutureList, new FutureCallback
>() {
-
- @Override
- public void onSuccess(final List
> newAsyncCloseCallback(@Nullable final Semaphore semaphore) {
- final Consumer
> newAsyncCloseCallback(@Nullable final Semaphore semaphore,
+ final boolean isInCloseProcess) {
+ final Consumer
>() {