This is an automated email from the ASF dual-hosted git repository.

elsloo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-trafficcontrol.git

commit 5a7fd581605370fe344c88d76792d9f84d2c66bb
Author: Rawlin Peters <rawlin_pet...@comcast.com>
AuthorDate: Tue Oct 31 16:12:31 2017 -0600

    Fix how deep NetworkNodes are loaded with a CacheLocation
    
    Lazily load Caches into a deep NetworkNode's CacheLocation rather than
    setting its CacheLocation and greedily loading Caches into it at the
    time of NetworkNode.generateTree(). This allows changes in Cache status
    to be reflected in deep CZF lookups (i.e. when a Cache is set to
    OFFLINE, stop deep routing to it). Whenever a new CRConfig is processed,
    clear out deep Caches from the CacheLocations so that they can be lazily
    loaded again (similar to how non-deep CacheLocations are reset to null).
---
 .../traffic_router/core/cache/CacheLocation.java   |   4 +
 .../traffic_router/core/config/ConfigHandler.java  |   2 +-
 .../traffic_router/core/loc/NetworkNode.java       | 108 +++++++++++----------
 .../traffic_router/core/router/TrafficRouter.java  |  17 ++++
 4 files changed, 77 insertions(+), 54 deletions(-)

diff --git 
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/cache/CacheLocation.java
 
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/cache/CacheLocation.java
index e2bf78d..7caf2a3 100644
--- 
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/cache/CacheLocation.java
+++ 
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/cache/CacheLocation.java
@@ -60,6 +60,10 @@ public class CacheLocation {
                        caches.put(cache.getId(), cache);
        }
 
+       public void clearCaches() {
+               caches.clear();
+       }
+
        @Override
        public boolean equals(final Object obj) {
                if (this == obj) {
diff --git 
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/config/ConfigHandler.java
 
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/config/ConfigHandler.java
index 53f3188..d9531a4 100644
--- 
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/config/ConfigHandler.java
+++ 
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/config/ConfigHandler.java
@@ -205,7 +205,6 @@ public class ConfigHandler {
                                parseCacheConfig(JsonUtils.getJsonNode(jo, 
"contentServers"), cacheRegister);
                                parseMonitorConfig(JsonUtils.getJsonNode(jo, 
"monitors"));
 
-                               NetworkNode.setCacheRegister(cacheRegister);
                                federationsWatcher.configure(config);
                                steeringWatcher.configure(config);
                                steeringWatcher.setCacheRegister(cacheRegister);
@@ -223,6 +222,7 @@ public class ConfigHandler {
                                 * then clear cache locations, the lazy loading 
should work as designed. See issue TC-401 for details.
                                 */
                                NetworkNode.getInstance().clearCacheLocations();
+                               
NetworkNode.getDeepInstance().clearCacheLocations(true);
                                setLastSnapshotTimestamp(sts);
                        } catch (ParseException e) {
                                isProcessing.set(false);
diff --git 
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/loc/NetworkNode.java
 
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/loc/NetworkNode.java
index 0b89d2e..c852184 100644
--- 
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/loc/NetworkNode.java
+++ 
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/loc/NetworkNode.java
@@ -20,11 +20,12 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.concurrent.CountDownLatch;
 
 import com.comcast.cdn.traffic_control.traffic_router.core.util.CidrAddress;
 import com.comcast.cdn.traffic_control.traffic_router.core.util.JsonUtils;
@@ -35,9 +36,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.log4j.Logger;
 
-import com.comcast.cdn.traffic_control.traffic_router.core.cache.Cache;
 import com.comcast.cdn.traffic_control.traffic_router.core.cache.CacheLocation;
-import com.comcast.cdn.traffic_control.traffic_router.core.cache.CacheRegister;
 
 public class NetworkNode implements Comparable<NetworkNode> {
     private static final Logger LOGGER = Logger.getLogger(NetworkNode.class);
@@ -46,14 +45,12 @@ public class NetworkNode implements Comparable<NetworkNode> 
{
     private static NetworkNode instance;
     private static NetworkNode deepInstance;
 
-    private static CacheRegister cacheRegister;
-    private static final CountDownLatch cacheRegisterLatch = new 
CountDownLatch(1);
-
     private CidrAddress cidrAddress;
     private String loc;
     private CacheLocation cacheLocation = null;
     private Geolocation geolocation = null;
     protected Map<NetworkNode,NetworkNode> children;
+    private Set<String> deepCacheNames;
 
     public static NetworkNode getInstance() {
         if (instance != null) {
@@ -83,21 +80,6 @@ public class NetworkNode implements Comparable<NetworkNode> {
         return deepInstance;
     }
 
-    public static void setCacheRegister(final CacheRegister cr) {
-        cacheRegister = cr;
-        cacheRegisterLatch.countDown();
-    }
-
-    public static CacheRegister getCacheRegisterBlocking() {
-        try {
-            cacheRegisterLatch.await();
-        } catch (InterruptedException e) {
-            LOGGER.warn(e);
-        } finally {
-            return cacheRegister;
-        }
-    }
-
     public static NetworkNode generateTree(final File f, final boolean 
verifyOnly, final boolean useDeep) throws IOException  {
         final ObjectMapper mapper = new ObjectMapper();
         return generateTree(mapper.readTree(f), verifyOnly, useDeep);
@@ -130,31 +112,8 @@ public class NetworkNode implements 
Comparable<NetworkNode> {
                     final double longitude = 
coordinates.get("longitude").asDouble();
                     geolocation = new Geolocation(latitude, longitude);
                 }
-                CacheLocation deepLoc = null;
-                if (useDeep) {
-                    try {
-                        final JsonNode caches = JsonUtils.getJsonNode(locData, 
"caches");
-                        for (final JsonNode cacheJson : caches) {
-                            final String cacheHostname = cacheJson.asText();
-                            if (deepLoc == null) {
-                                deepLoc = new CacheLocation( "deep." + loc, 
new Geolocation(0.0, 0.0));  // TODO JvD
-                            }
-                            // Get the cache from the cacheregister here - 
don't create a new cache due to the deep file, only reuse the
-                            // ones we already know about.
-                            final Cache cache = 
getCacheRegisterBlocking().getCacheMap().get(cacheHostname);
-                            if (cache == null) {
-                                LOGGER.warn("DDC: deep cache entry " + 
cacheHostname + " not found in crconfig server list (it might not belong to 
this CDN)");
-                            } else {
-                                LOGGER.info("DDC: Adding " + cacheHostname + " 
to " + deepLoc.getId() + ".");
-                                deepLoc.addCache(cache);
-                            }
-                        }
-                    } catch (JsonUtilsException ex) {
-                        LOGGER.warn("An exception was caught while accessing 
the caches key of " + loc + " in the incoming coverage zone file: " + 
ex.getMessage());
-                    }
-                }
 
-                if (!addNetworkNodesToRoot(root, locData, loc, deepLoc, 
geolocation, useDeep)) {
+                if (!addNetworkNodesToRoot(root, loc, locData, geolocation, 
useDeep)) {
                     return null;
                 }
             }
@@ -177,8 +136,11 @@ public class NetworkNode implements 
Comparable<NetworkNode> {
         return null;
     }
 
-    private static boolean addNetworkNodesToRoot(final SuperNode root, final 
JsonNode locData, final String loc,
-                                                 final CacheLocation deepLoc, 
final Geolocation geolocation, final boolean useDeep) {
+    private static boolean addNetworkNodesToRoot(final SuperNode root, final 
String loc, final JsonNode locData,
+                                                 final Geolocation 
geolocation, final boolean useDeep) {
+        CacheLocation deepLoc = new CacheLocation( "deep." + loc, geolocation 
!= null ? geolocation : new Geolocation(0.0, 0.0));  // TODO JvD
+        final Set<String> cacheNames = parseDeepCacheNames(locData);
+
         for (final String key : new String[]{"network6", "network"}) {
             try {
                 for (final JsonNode network : JsonUtils.getJsonNode(locData, 
key)) {
@@ -186,7 +148,12 @@ public class NetworkNode implements 
Comparable<NetworkNode> {
 
                     try {
                         final NetworkNode nn = new NetworkNode(ip, loc, 
geolocation);
-                        if (useDeep && deepLoc != null) { // for deepLoc, we 
add the location here; normally it gets added by setLocation.
+                        if (useDeep) {
+                            // For a deep NetworkNode, we set the 
CacheLocation here without any Caches.
+                            // The deep Caches will be lazily loaded in 
getCoverageZoneCacheLocation() where we have
+                            // access to the latest CacheRegister, similar to 
how normal NetworkNodes are lazily loaded
+                            // with a CacheLocation.
+                            nn.setDeepCacheNames(cacheNames);
                             nn.setCacheLocation(deepLoc);
                         }
                         if ("network6".equals(key)) {
@@ -206,6 +173,25 @@ public class NetworkNode implements 
Comparable<NetworkNode> {
         return true;
     }
 
+    private static Set<String> parseDeepCacheNames(JsonNode locationData) {
+        final Set<String> cacheNames = new HashSet<String>();
+        final JsonNode cacheArray;
+
+        try {
+            cacheArray = JsonUtils.getJsonNode(locationData, "caches");
+        } catch (JsonUtilsException ex) {
+            return cacheNames;
+        }
+
+        for (final JsonNode cache : cacheArray) {
+            final String cacheName = cache.asText();
+            if (!cacheName.isEmpty()) {
+                cacheNames.add(cacheName);
+            }
+        }
+        return cacheNames;
+    }
+
     public NetworkNode(final String str) throws NetworkNodeException {
         this(str, null);
     }
@@ -302,6 +288,14 @@ public class NetworkNode implements 
Comparable<NetworkNode> {
         this.cacheLocation = cacheLocation;
     }
 
+    public Set<String> getDeepCacheNames() {
+        return deepCacheNames;
+    }
+
+    public void setDeepCacheNames(final Set<String> deepCacheNames) {
+        this.deepCacheNames = deepCacheNames;
+    }
+
     public int size() {
         if (children == null) {
             return 1;
@@ -317,22 +311,30 @@ public class NetworkNode implements 
Comparable<NetworkNode> {
     }
 
     public void clearCacheLocations() {
+        clearCacheLocations(false);
+    }
+
+    public void clearCacheLocations(boolean clearCachesOnly) {
         synchronized(this) {
-            cacheLocation = null;
+            if (clearCachesOnly && cacheLocation != null) {
+                cacheLocation.clearCaches();
+            } else {
+                cacheLocation = null;
+            }
 
             if (this instanceof SuperNode) {
                 final SuperNode superNode = (SuperNode) this;
 
                 if (superNode.children6 != null) {
                     for (final NetworkNode child : 
superNode.children6.keySet()) {
-                        child.clearCacheLocations();
+                        child.clearCacheLocations(clearCachesOnly);
                     }
                 }
             }
 
             if (children != null) {
                 for (final NetworkNode child : children.keySet()) {
-                    child.clearCacheLocations();
+                    child.clearCacheLocations(clearCachesOnly);
                 }
             }
         }
diff --git 
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java
 
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java
index 705ec5b..68dfb6b 100644
--- 
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java
+++ 
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java
@@ -657,6 +657,11 @@ public class TrafficRouter {
                final DeliveryService deliveryService = 
cacheRegister.getDeliveryService(deliveryServiceId);
                CacheLocation cacheLocation = networkNode.getCacheLocation();
 
+               if (useDeep && cacheLocation != null && 
cacheLocation.getCaches().isEmpty()) {
+                       // lazily load deep Caches into the deep CacheLocation
+                       loadDeepCaches(networkNode, cacheLocation);
+               }
+
                if (cacheLocation != null && 
!getSupportingCaches(cacheLocation.getCaches(), deliveryService).isEmpty()) {
                        return cacheLocation;
                }
@@ -683,6 +688,18 @@ public class TrafficRouter {
                return 
getClosestCacheLocation(cacheRegister.filterAvailableLocations(deliveryServiceId),
 networkNode.getGeolocation(), 
cacheRegister.getDeliveryService(deliveryServiceId));
        }
 
+       private void loadDeepCaches(NetworkNode networkNode, CacheLocation 
cacheLocation) {
+               if (networkNode.getDeepCacheNames() != null) {
+                       for (final String deepCacheName : 
networkNode.getDeepCacheNames()) {
+                               final Cache deepCache = 
cacheRegister.getCacheMap().get(deepCacheName);
+                               if (deepCache != null) {
+                                       LOGGER.debug("DDC: Adding " + 
deepCacheName + " to " + cacheLocation.getId());
+                                       cacheLocation.addCache(deepCache);
+                               }
+                       }
+               }
+       }
+
        public CacheLocation getDeepCoverageZoneCacheLocation(final String ip, 
final DeliveryService deliveryService) {
                return getCoverageZoneCacheLocation(ip, deliveryService, true);
        }

-- 
To stop receiving notification emails like this one, please contact
els...@apache.org.

Reply via email to