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.