Flush page and re build cache in all dispatchers | Community
Skip to main content
veerareddyc1015
Level 3
June 11, 2025

Flush page and re build cache in all dispatchers

  • June 11, 2025
  • 3 replies
  • 565 views

Hi Team,

 

Can anyone please suggest a solution for the following scenario?

I need to flush the Dispatcher cache and regenerate it across all Dispatcher instances for a specific AEM page, without publishing or activating the page.
I'm looking for a solution that can be triggered directly from AEM, preferably using a scheduler that runs at a configurable interval.

Any guidance, sample code, or best practices to achieve this would be greatly appreciated.

 

Thanks in Advance.

Veera

3 replies

giuseppebaglio
Level 10
June 11, 2025

hi @veerareddyc1015, you can force the behaviour into the dispatcher with a POST call

POST /dispatcher/invalidate.cache HTTP/1.1 CQ-Action: Activate `Content-Type: text/plain CQ-Handle: path-pattern Content-Length: numchars in bodypage_path0 page_path1 ... page_pathn

as explained here.You can set up a scheduler for each publishing instance to trigger a POST call, ensuring that all dispatchers in the infrastructure will rebuild the cache. The scheduler must compute all the links for the website, similar to a sitemap, so that these links can be included in the body of the POST request.

 

veerareddyc1015
Level 3
June 13, 2025

Thank you for the response. I'm using AEM 6.5.22.0 and have configured it as shown below. The cached page is getting removed as expected upon activation, but it's not being re-cached. Could you please let me know if I'm missing something?

 

giuseppebaglio
Level 10
July 2, 2025

Adjusting the replication agent is ineffective because it is essential for the post to function correctly. Specifically, the header "CQ-Handle" must include the deepest page (you can refer to this documentation for clarification) among those to be invalidated. If this condition is not met, the resource will not be re-cached.

 

Here is the code that works correctly:

CloseableHttpResponse invalidateAndRecache(String dispatcherUrl, Set<String> pagesToInvalidate, String domain, String cqHandlePath) throws IOException { HttpPost post = new HttpPost(dispatcherUrl); post.addHeader("CQ-Action", "Activate"); post.addHeader("CQ-Handle", cqHandlePath); post.addHeader("Host", domain); post.addHeader("CQ-Action-Scope", "ResourceOnly"); post.addHeader("Content-Type", "text/plain"); String bodyString = StringUtils.join(pagesToInvalidate, "\n"); StringEntity body = new StringEntity(bodyString); post.setEntity(body); CloseableHttpResponse execute = httpClientService.getConfiguredHttpClient().execute(post); return execute; } @Component(service = HttpClientService.class, immediate = true) public class HttpClientServiceImpl implements HttpClientService { private CloseableHttpClient httpClient; @9944223 public CloseableHttpClient getConfiguredHttpClient() { [...] return this.httpClient; } }

 

 

ButhpurKiran
Level 4
June 11, 2025

if you are looking for auto flush based on scheduled frequencies, OSGI config can be helpful

1. Create OSGI config that gets reflected in Felix Server(/system/console) --> Configuration tab

DispatcherCacheRefresherConfig.java

import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.osgi.service.metatype.annotations.AttributeDefinition;

@ObjectClassDefinition(name = "Dispatcher Cache Refresher Config")
public @interface DispatcherCacheRefresherConfig {

@AttributeDefinition(name = "Page Path", description = "Path of the page to flush and regenerate")
String pagePath();

@AttributeDefinition(name = "Dispatcher Flush URL", description = "URL used to flush the dispatcher cache")
String flushUrl();

@AttributeDefinition(name = "Cron Expression", description = "Cron expression for scheduler")
String schedulerExpression() default "0 0/30 * * * ?"; // every 30 min

@AttributeDefinition(name = "Enabled", description = "Enable or disable the job")
boolean enabled() default true;
}


2. Create a Scheduler to execute job based on the config parameters defined in above OSGI Conf

DispatcherCacheRefresher.java

import org.osgi.service.component.annotations.*;
import org.osgi.service.metatype.annotations.Designate;
import org.apache.sling.commons.scheduler.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.HttpURLConnection;
import java.net.URL;

@8220494(service = Runnable.class, immediate = true)
@Designate(ocd = DispatcherCacheRefresherConfig.class)
public class DispatcherCacheRefresher implements Runnable {

private final Logger log = LoggerFactory.getLogger(this.getClass());

@3214626
private Scheduler scheduler;

private DispatcherCacheRefresherConfig config;
private static final String osgiJob = "dispatcher-cache-refresher";

@580286
@9182423
protected void activate(DispatcherCacheRefresherConfig config) {
this.config = config;

if (config.enabled()) {
try {
scheduler.remove(osgiJob);
scheduler.addJob(osgiJob, this, null, config.schedulerExpression(), true);
log.info("Dispatcher Cache Refresher job scheduled.");
} catch (Exception e) {
log.error("Error scheduling job", e);
}
}
}

@3038739
protected void deactivate() {
scheduler.remove(osgiJob);
}

@9944223
public void run() {
try {
flushDispatcherCache(config.flushUrl());
regeneratePage(config.pagePath());
} catch (Exception e) {
log.error("Error in dispatcher cache refresher job", e);
}
}

private void flushDispatcherCache(String flushUrl) throws Exception {
log.info("Flushing Dispatcher Cache at {}", flushUrl);
HttpURLConnection con = (HttpURLConnection) new URL(flushUrl).openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
log.info("Flush response code: {}", responseCode);
}

private void regeneratePage(String pagePath) throws Exception {
String url = "http://localhost:4503" + pagePath + ".html"; // assuming publish or internal dispatcher
log.info("Regenerating page by requesting: {}", url);
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
log.info("Page regeneration response code: {}", responseCode);
}
}

Now, 

  • Deploy the OSGi service.

  • Configure the values in system/console/configmgr

  • Verify cache files are removed and regenerated under the dispatcher docroot(folder created in your webtop/mac/server

    Hope this gives info you are looking for.

    Thanks
    Kiran Buthpur

 

kautuk_sahni
Community Manager
Community Manager
July 1, 2025

@veerareddyc1015 

Just checking in — were you able to resolve your issue?
We’d love to hear how things worked out. If the suggestions above helped, marking a response as correct can guide others with similar questions. And if you found another solution, feel free to share it — your insights could really benefit the community. Thanks again for being part of the conversation!

Kautuk Sahni