Committed by
Gerrit Code Review
Detect circular app dependency
Change-Id: Ib3e2d802dfe3675ef5c8ef8818c1127ed145adf1
Showing
1 changed file
with
21 additions
and
0 deletions
| ... | @@ -17,6 +17,7 @@ package org.onosproject.store.app; | ... | @@ -17,6 +17,7 @@ package org.onosproject.store.app; |
| 17 | 17 | ||
| 18 | import com.google.common.base.Charsets; | 18 | import com.google.common.base.Charsets; |
| 19 | import com.google.common.collect.ImmutableSet; | 19 | import com.google.common.collect.ImmutableSet; |
| 20 | +import com.google.common.collect.Lists; | ||
| 20 | import com.google.common.collect.Maps; | 21 | import com.google.common.collect.Maps; |
| 21 | import com.google.common.collect.Multimap; | 22 | import com.google.common.collect.Multimap; |
| 22 | import com.google.common.collect.Sets; | 23 | import com.google.common.collect.Sets; |
| ... | @@ -57,6 +58,8 @@ import org.slf4j.Logger; | ... | @@ -57,6 +58,8 @@ import org.slf4j.Logger; |
| 57 | import java.io.ByteArrayInputStream; | 58 | import java.io.ByteArrayInputStream; |
| 58 | import java.io.IOException; | 59 | import java.io.IOException; |
| 59 | import java.io.InputStream; | 60 | import java.io.InputStream; |
| 61 | +import java.util.List; | ||
| 62 | +import java.util.Optional; | ||
| 60 | import java.util.Set; | 63 | import java.util.Set; |
| 61 | import java.util.concurrent.CountDownLatch; | 64 | import java.util.concurrent.CountDownLatch; |
| 62 | import java.util.concurrent.ExecutorService; | 65 | import java.util.concurrent.ExecutorService; |
| ... | @@ -98,6 +101,8 @@ public class GossipApplicationStore extends ApplicationArchive | ... | @@ -98,6 +101,8 @@ public class GossipApplicationStore extends ApplicationArchive |
| 98 | 101 | ||
| 99 | private static final int APP_LOAD_DELAY_MS = 500; | 102 | private static final int APP_LOAD_DELAY_MS = 500; |
| 100 | 103 | ||
| 104 | + private static List<String> pendingApps = Lists.newArrayList(); | ||
| 105 | + | ||
| 101 | public enum InternalState { | 106 | public enum InternalState { |
| 102 | INSTALLED, ACTIVATED, DEACTIVATED | 107 | INSTALLED, ACTIVATED, DEACTIVATED |
| 103 | } | 108 | } |
| ... | @@ -197,6 +202,8 @@ public class GossipApplicationStore extends ApplicationArchive | ... | @@ -197,6 +202,8 @@ public class GossipApplicationStore extends ApplicationArchive |
| 197 | } | 202 | } |
| 198 | 203 | ||
| 199 | private Application loadFromDisk(String appName) { | 204 | private Application loadFromDisk(String appName) { |
| 205 | + pendingApps.add(appName); | ||
| 206 | + | ||
| 200 | for (int i = 0; i < MAX_LOAD_RETRIES; i++) { | 207 | for (int i = 0; i < MAX_LOAD_RETRIES; i++) { |
| 201 | try { | 208 | try { |
| 202 | // Directly return if app already exists | 209 | // Directly return if app already exists |
| ... | @@ -204,19 +211,33 @@ public class GossipApplicationStore extends ApplicationArchive | ... | @@ -204,19 +211,33 @@ public class GossipApplicationStore extends ApplicationArchive |
| 204 | if (appId != null) { | 211 | if (appId != null) { |
| 205 | Application application = getApplication(appId); | 212 | Application application = getApplication(appId); |
| 206 | if (application != null) { | 213 | if (application != null) { |
| 214 | + pendingApps.remove(appName); | ||
| 207 | return application; | 215 | return application; |
| 208 | } | 216 | } |
| 209 | } | 217 | } |
| 210 | 218 | ||
| 211 | ApplicationDescription appDesc = getApplicationDescription(appName); | 219 | ApplicationDescription appDesc = getApplicationDescription(appName); |
| 220 | + | ||
| 221 | + Optional<String> loop = appDesc.requiredApps().stream() | ||
| 222 | + .filter(app -> pendingApps.contains(app)).findAny(); | ||
| 223 | + if (loop.isPresent()) { | ||
| 224 | + log.error("Circular app dependency detected: {} -> {}", pendingApps, loop.get()); | ||
| 225 | + pendingApps.remove(appName); | ||
| 226 | + return null; | ||
| 227 | + } | ||
| 228 | + | ||
| 212 | boolean success = appDesc.requiredApps().stream() | 229 | boolean success = appDesc.requiredApps().stream() |
| 213 | .noneMatch(requiredApp -> loadFromDisk(requiredApp) == null); | 230 | .noneMatch(requiredApp -> loadFromDisk(requiredApp) == null); |
| 231 | + pendingApps.remove(appName); | ||
| 232 | + | ||
| 214 | return success ? create(appDesc, false) : null; | 233 | return success ? create(appDesc, false) : null; |
| 234 | + | ||
| 215 | } catch (Exception e) { | 235 | } catch (Exception e) { |
| 216 | log.warn("Unable to load application {} from disk; retrying", appName); | 236 | log.warn("Unable to load application {} from disk; retrying", appName); |
| 217 | randomDelay(RETRY_DELAY_MS); //FIXME: This is a deliberate hack; fix in Falcon | 237 | randomDelay(RETRY_DELAY_MS); //FIXME: This is a deliberate hack; fix in Falcon |
| 218 | } | 238 | } |
| 219 | } | 239 | } |
| 240 | + pendingApps.remove(appName); | ||
| 220 | return null; | 241 | return null; |
| 221 | } | 242 | } |
| 222 | 243 | ... | ... |
-
Please register or login to post a comment