protected PageInfo buildCachedPageInfo( HttpServletRequest request, HttpServletResponse response, CacheStatus cacheStatus) throws Exception { Timer timer = new Timer(getCachedUri(request)); timer.start(); String key = calculateKey(request); PageInfo pageInfo; ValueWrapper element = cacheStatus.valueWrapper; log.debug("Serving cached content for {}", key); pageInfo = (PageInfo) element.get(); for (Map.Entry<String, ? extends Serializable> entry : pageInfo.getRequestAttributes().entrySet()) { request.setAttribute(entry.getKey(), entry.getValue()); } // As the page is cached, we need to add an instance of the associated // controller to the request. This is required by GrailsLayoutDecoratorMapper // to pick the appropriate layout. if (StringUtils.hasLength(getContext().getControllerName())) { Object controller = lookupController(getContext().getControllerClass()); request.setAttribute(GrailsApplicationAttributes.CONTROLLER, controller); } timer.stop(true); response.addHeader(X_CACHED, String.valueOf(true)); return pageInfo; }
protected PageInfo buildNewPageInfo( HttpServletRequest request, HttpServletResponse response, FilterChain chain, CacheStatus cacheStatus, Map<String, Collection<CacheOperationContext>> operationsByType) throws Exception { Timer timer = new Timer(getCachedUri(request)); timer.start(); String key = calculateKey(request); PageInfo pageInfo; try { // Page is not cached - build the response, cache it, and send to client pageInfo = buildPage(request, response, chain); if (pageInfo.isOk()) { Object noCache = pageInfo.getCacheDirectives().get("no-cache"); if (noCache instanceof Boolean && ((Boolean) noCache)) { log.debug("Response ok but Cache-Control: no-cache is present, not caching"); releaseCacheLocks(operationsByType, key); } else { Collection<Cache> caches = new ArrayList<Cache>(); for (CacheOperationContext operationContext : operationsByType.get(UPDATE)) { for (Cache cache : operationContext.getCaches()) { caches.add(cache); } } update(caches, pageInfo, cacheStatus, key); } } else { for (CacheOperationContext operationContext : operationsByType.get(UPDATE)) { for (Cache cache : operationContext.getCaches()) { log.debug( "Response not ok ({}). Putting null into cache {} with key {}", pageInfo.getStatusCode(), cache.getName(), key); } } releaseCacheLocks(operationsByType, key); } } catch (Exception e) { if ("net.sf.ehcache.constructs.blocking.LockTimeoutException" .equals(e.getClass().getName())) { // do not release the lock, because you never acquired it throw e; } // Must unlock the cache if the above fails. Will be logged at Filter releaseCacheLocks(operationsByType, key); throw e; } timer.stop(false); response.addHeader(X_CACHED, String.valueOf(false)); return pageInfo; }