Bug 2019: Have FeatureConfigPusher retry installedFeature check 96/11496/1
authorEd Warnicke <eaw@cisco.com>
Tue, 23 Sep 2014 17:08:42 +0000 (12:08 -0500)
committerEd Warnicke <eaw@cisco.com>
Tue, 23 Sep 2014 17:23:45 +0000 (12:23 -0500)
until it succeeds (or 100ms pass).

Karaf reports FeatureEvents before it marks the features
installed.  It also only guarantees complete info about
the features when you read the installed ones.  This
is causing a race condition that is at the root of 2019.

So this patch retries at 1ms intervals until we see

Change-Id: I67080475fc4b2dc2f053a286424f676f89164b6e
Signed-off-by: Ed Warnicke <eaw@cisco.com>
opendaylight/config/config-persister-feature-adapter/src/main/java/org/opendaylight/controller/configpusherfeature/internal/ConfigFeaturesListener.java
opendaylight/config/config-persister-feature-adapter/src/main/java/org/opendaylight/controller/configpusherfeature/internal/FeatureConfigPusher.java

index f5f1b856acac1647f00da03c194d0925e246d3e4..b8f18960d109f60d5d33e3683035784387ee0a86 100644 (file)
@@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory;
 
 public class ConfigFeaturesListener implements  FeaturesListener,  AutoCloseable {
     private static final Logger logger = LoggerFactory.getLogger(ConfigFeaturesListener.class);
-    private static final int QUEUE_SIZE = 100;
+    private static final int QUEUE_SIZE = 1000;
     private BlockingQueue<FeatureEvent> queue = new LinkedBlockingQueue<FeatureEvent>(QUEUE_SIZE);
     Thread pushingThread = null;
 
index 57052f9d6003fc14a84761acc146d1bf678e0f7a..17099f9d3355d948c877538bc76b0f1f8f21285e 100644 (file)
@@ -27,6 +27,7 @@ import com.google.common.collect.LinkedHashMultimap;
 public class FeatureConfigPusher {
     private static final Logger logger = LoggerFactory.getLogger(FeatureConfigPusher.class);
     private static final int MAX_RETRIES=100;
+    private static final int RETRY_PAUSE_MILLIS=1;
     private FeaturesService featuresService = null;
     private ConfigPusher pusher = null;
     /*
@@ -83,30 +84,30 @@ public class FeatureConfigPusher {
     }
 
     private boolean isInstalled(Feature feature) {
-        List<Feature> installedFeatures= null;
-        boolean cont = true;
-        int retries = 0;
-        while(cont) {
+        for(int retries=0;retries<MAX_RETRIES;retries++) {
             try {
-                installedFeatures = Arrays.asList(featuresService.listInstalledFeatures());
-                break;
+                List<Feature> installedFeatures = Arrays.asList(featuresService.listInstalledFeatures());
+                if(installedFeatures.contains(feature)) {
+                    return true;
+                } else {
+                    logger.warn("Karaf featuresService.listInstalledFeatures() has not yet finished installing feature (retry {}) {} {}",retries,feature.getName(),feature.getVersion());
+                }
             } catch (Exception e) {
                 if(retries < MAX_RETRIES) {
                     logger.warn("Karaf featuresService.listInstalledFeatures() has thrown an exception, retry {}, Exception {}", retries,e);
-                    try {
-                        Thread.sleep(1);
-                    } catch (InterruptedException e1) {
-                        throw new IllegalStateException(e1);
-                    }
-                    retries++;
-                    continue;
                 } else {
                     logger.error("Giving up on Karaf featuresService.listInstalledFeatures() which has thrown an exception, retry {}, Exception {}", retries,e);
                     throw e;
                 }
             }
+            try {
+                Thread.sleep(RETRY_PAUSE_MILLIS);
+            } catch (InterruptedException e1) {
+                throw new IllegalStateException(e1);
+            }
         }
-        return installedFeatures.contains(feature);
+        logger.error("Giving up (after {} retries) on Karaf featuresService.listInstalledFeatures() which has not yet finished installing feature {} {}",MAX_RETRIES,feature.getName(),feature.getVersion());
+        return false;
     }
 
     private LinkedHashSet<FeatureConfigSnapshotHolder> pushConfig(LinkedHashSet<FeatureConfigSnapshotHolder> configs) throws InterruptedException {