public virtual string GetRouteById(UmbracoContext umbracoContext, bool preview, int contentId) { // try to get from cache if not previewing var route = preview ? null : _routesCache.GetRoute(contentId); // if found in cache then return if (route != null) { return(route); } // else actually determine the route route = DetermineRouteById(umbracoContext, preview, contentId); // node not found if (route == null) { return(null); } // cache the route BUT do NOT trust it as it can be a colliding route // meaning if we GetRouteById again, we'll get it from cache, but it // won't be used for inbound routing if (preview == false) { _routesCache.Store(contentId, route, false); } return(route); }
public virtual string GetRouteById(UmbracoContext umbracoContext, bool preview, int contentId) { // try to get from cache if not previewing var route = preview ? null : _routesCache.GetRoute(contentId); // if found in cache then return if (route != null) { return(route); } // else actually determine the route route = DetermineRouteById(umbracoContext, preview, contentId); // node not found if (route == null) { return(null); } // find the content back, detect routes collisions: we should find ourselves back, // else it means that another content with "higher priority" is sharing the same route. // perf impact: // - non-colliding, adds one complete "by route" lookup, only on the first time a url is computed (then it's cached anyways) // - colliding, adds one "by route" lookup, the first time the url is computed, then one dictionary looked each time it is computed again // assuming no collisions, the impact is one complete "by route" lookup the first time each url is computed // // U4-9121 - this lookup is too expensive when computing a large amount of urls on a front-end (eg menu) // ... thinking about moving the lookup out of the path into its own async task, so we are not reporting errors // in the back-office anymore, but at least we are not polluting the cache // instead, refactored DeterminedIdByRoute to stop using XPath, with a 16x improvement according to benchmarks // will it be enough? var loopId = preview ? 0 : _routesCache.GetNodeId(route); // might be cached already in case of collision if (loopId == 0) { var content = DetermineIdByRoute(umbracoContext, preview, route, GlobalSettings.HideTopLevelNodeFromPath); // add the other route to cache so next time we have it already if (content != null && preview == false) { AddToCacheIfDeepestRoute(umbracoContext, content, route); } loopId = content == null ? 0 : content.Id; // though... 0 here would be quite weird? } // cache if we have a route and not previewing and it's not a colliding route // (the result of DetermineRouteById is always the deepest route) if (/*route != null &&*/ preview == false && loopId == contentId) { _routesCache.Store(contentId, route); } // return route if no collision, else report collision return(loopId == contentId ? route : ("err/" + loopId)); }
public virtual string GetRouteById(UmbracoContext umbracoContext, bool preview, int contentId) { // try to get from cache if not previewing var route = preview ? null : _routesCache.GetRoute(contentId); // if found in cache then return if (route != null) { return(route); } // else actually determine the route route = DetermineRouteById(umbracoContext, preview, contentId); // cache if we have a route and not previewing if (route != null && !preview) { _routesCache.Store(contentId, route); } return(route); }