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