Clearing output cache in a multi server environment

This is a follow up to the previous Acting on Optimizely Remote Events article. While still working with the older Optimizely 11 you may rely on the Remote Event functionality to clear cache. However, in some cases you may need to build on this functionality to clear the output cache on other servers manually.

In a previous project we used this to clear the cache of virtual pages (i.e. we had a single Optimizely page instance which presented different information based on a custom id number, together with a friendly URL rewriting functionality).

This first method is to be called when an update to data connected to an Id is detected. Could be in an import method, an update event or such. It uses the Optimizely cache manager, which in turn will be sending out cache clearing events to other machines.

public async Task ClearAllCacheAsync(IEnumerable<CustomId> customIds)
{
  _ = customIds ?? throw new ArgumentNullException(nameof(customIds));

  ContentReference reference = ... // Get the reference to the single page instance.

  foreach (CustomId customId in customIds)
  {
    _cacheManager.Service.ClearCache(customId);

    string url = await _customFriendlyUrlMaker.Service.FriendlyUrlToAsync(reference, customId).ConfigureAwait(false);

    ClearOutputCacheInner(url);
  }
}

The next method is to be called from the MessageReceived_MyHandler described in the previous article (see top). It will be clearing the output cache on the remote machines once they receive the cache clearing remote event sent by Optimizely’s cache manager. Note that this event is not to trigger the Optimizely cache manager code for clearing cache, as it would result in a cache clearing loop between servers.

public async Task ClearOutputCacheAsync(CustomId customId)
{
  _ = customId ?? throw new ArgumentNullException(nameof(customId));

  ContentReference reference = ... // Get the reference to the single page instance.

  string url = await _customFriendlyUrlMaker.Service.FriendlyUrlToAsync(reference, customId).ConfigureAwait(false);

  ClearOutputCacheInner(url);
}

Finally, the inner cache clearing method used by both previous. All it does is clearing the output cache using the HttpResponse RemoteOutputCacheItem method. In our case, we had multiple regional instances of the same page, thus required to remove them all from the cache.

private void ClearOutputCacheInner(string url)
{
  // National URL-key format: "/path/single-instance-page/friendly-url-to-id/"
  HttpResponse.RemoveOutputCacheItem(url);
  foreach (Region region in _regionRepository.Service.GetAllRegions())
  {
    // Regional URL-key format: "/region/path/single-instance-page/friendly-url-to-id/"
    HttpResponse.RemoveOutputCacheItem($"/{region.Slug}{url}");
  }
}