Speed up OsgiBundleScanningSchemaService close
[mdsal.git] / dom / mdsal-dom-broker / src / main / java / org / opendaylight / mdsal / dom / broker / osgi / OsgiBundleScanningSchemaService.java
index 540a5d8239c6b7eb48c610e153e9e75de761ffec..bc057e74f4d5a8067560c8f57e7c236ecd5aa890 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.mdsal.dom.broker.osgi;
 
 import static com.google.common.base.Preconditions.checkState;
+
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -37,7 +38,8 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class OsgiBundleScanningSchemaService implements SchemaContextProvider, DOMSchemaService, ServiceTrackerCustomizer<SchemaContextListener, SchemaContextListener>, AutoCloseable {
+public class OsgiBundleScanningSchemaService implements SchemaContextProvider, DOMSchemaService,
+        ServiceTrackerCustomizer<SchemaContextListener, SchemaContextListener>, AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(OsgiBundleScanningSchemaService.class);
 
     private final ListenerRegistry<SchemaContextListener> listeners = new ListenerRegistry<>();
@@ -48,20 +50,21 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
     private ServiceTracker<SchemaContextListener, SchemaContextListener> listenerTracker;
     private BundleTracker<Iterable<Registration>> bundleTracker;
     private boolean starting = true;
+    private volatile boolean stopping;
     private static OsgiBundleScanningSchemaService instance;
 
     private OsgiBundleScanningSchemaService(final BundleContext context) {
         this.context = Preconditions.checkNotNull(context);
     }
 
-    public synchronized static OsgiBundleScanningSchemaService createInstance(final BundleContext ctx) {
+    public static synchronized OsgiBundleScanningSchemaService createInstance(final BundleContext ctx) {
         Preconditions.checkState(instance == null);
         instance = new OsgiBundleScanningSchemaService(ctx);
         instance.start();
         return instance;
     }
 
-    public synchronized static OsgiBundleScanningSchemaService getInstance() {
+    public static synchronized OsgiBundleScanningSchemaService getInstance() {
         Preconditions.checkState(instance != null, "Global Instance was not instantiated");
         return instance;
     }
@@ -83,8 +86,10 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
         checkState(context != null);
         LOG.debug("start() starting");
 
-        listenerTracker = new ServiceTracker<>(context, SchemaContextListener.class, OsgiBundleScanningSchemaService.this);
-        bundleTracker = new BundleTracker<>(context, Bundle.RESOLVED | Bundle.STARTING |
+        listenerTracker = new ServiceTracker<>(context, SchemaContextListener.class,
+                OsgiBundleScanningSchemaService.this);
+        bundleTracker = new BundleTracker<>(context, Bundle.RESOLVED | Bundle.STARTING
+                |
                 Bundle.STOPPING | Bundle.ACTIVE, scanner);
         bundleTracker.open();
 
@@ -113,9 +118,10 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
     }
 
     @Override
-    public synchronized ListenerRegistration<SchemaContextListener> registerSchemaContextListener(final SchemaContextListener listener) {
+    public synchronized ListenerRegistration<SchemaContextListener>
+        registerSchemaContextListener(final SchemaContextListener listener) {
         final Optional<SchemaContext> potentialCtx = contextResolver.getSchemaContext();
-        if(potentialCtx.isPresent()) {
+        if (potentialCtx.isPresent()) {
             listener.onGlobalContextUpdated(potentialCtx.get());
         }
         return listeners.register(listener);
@@ -123,6 +129,7 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
 
     @Override
     public void close() {
+        stopping = true;
         if (bundleTracker != null) {
             bundleTracker.close();
         }
@@ -135,6 +142,7 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
         }
     }
 
+    @SuppressWarnings("checkstyle:IllegalCatch")
     private synchronized void updateContext(final SchemaContext snapshot) {
         final Object[] services = listenerTracker.getServices();
         for (final ListenerRegistration<SchemaContextListener> listener : listeners) {
@@ -156,6 +164,7 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
         }
     }
 
+    @SuppressWarnings("checkstyle:IllegalCatch")
     private class BundleScanner implements BundleTrackerCustomizer<Iterable<Registration>> {
         @Override
         public Iterable<Registration> addingBundle(final Bundle bundle, final BundleEvent event) {
@@ -198,9 +207,10 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
          * {@link #getYangStoreSnapshot()} will throw exception. There is no
          * rollback.
          */
-
+        @SuppressWarnings("checkstyle:IllegalCatch")
         @Override
-        public synchronized void removedBundle(final Bundle bundle, final BundleEvent event, final Iterable<Registration> urls) {
+        public synchronized void removedBundle(final Bundle bundle, final BundleEvent event,
+                final Iterable<Registration> urls) {
             for (final Registration url : urls) {
                 try {
                     url.close();
@@ -210,9 +220,10 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
             }
 
             final int numUrls = Iterables.size(urls);
-            if(numUrls > 0 ) {
-                if(LOG.isDebugEnabled()) {
-                    LOG.debug("removedBundle: {}, state: {}, # urls: {}", bundle.getSymbolicName(), bundle.getState(), numUrls);
+            if (numUrls > 0 ) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("removedBundle: {}, state: {}, # urls: {}", bundle.getSymbolicName(),
+                            bundle.getState(), numUrls);
                 }
 
                 tryToUpdateSchemaContext();
@@ -232,12 +243,12 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
     }
 
     public synchronized void tryToUpdateSchemaContext() {
-        if (starting) {
+        if (starting || stopping) {
             return;
         }
         final Optional<SchemaContext> schema = contextResolver.getSchemaContext();
-        if(schema.isPresent()) {
-            if(LOG.isDebugEnabled()) {
+        if (schema.isPresent()) {
+            if (LOG.isDebugEnabled()) {
                 LOG.debug("Got new SchemaContext: # of modules {}", schema.get().getAllModuleIdentifiers().size());
             }
 
@@ -246,12 +257,14 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D
     }
 
     @Override
-    public void modifiedService(final ServiceReference<SchemaContextListener> reference, final SchemaContextListener service) {
+    public void modifiedService(final ServiceReference<SchemaContextListener> reference,
+            final SchemaContextListener service) {
         // NOOP
     }
 
     @Override
-    public void removedService(final ServiceReference<SchemaContextListener> reference, final SchemaContextListener service) {
+    public void removedService(final ServiceReference<SchemaContextListener> reference,
+            final SchemaContextListener service) {
         context.ungetService(reference);
     }
 }