I would use a remote event that can be raised on the CM server and subscribed to by the CD servers. When the event is raised, an event handler can execute on the CD servers clearing the cache.
This is the mechanism used by the HtmlCacheClearer
handler that comes with Sitecore, you can see how it is setup in the default Sitecore.config
:
<event name="publish:end">
<handler type="Sitecore.Publishing.HtmlCacheClearer, Sitecore.Kernel" method="ClearCache">
<sites hint="list">
<site>website</site>
</sites>
</handler>
</event>
<event name="publish:end:remote">
<handler type="Sitecore.Publishing.HtmlCacheClearer, Sitecore.Kernel" method="ClearCache">
<sites hint="list">
<site>website</site>
</sites>
</handler>
</event>
The publish:end
event is raised on the local environment when publishing ends (i.e. the CM server), and the publish:end:remote
event is raised on remote environments (i.e. the CD servers).
It is fairly straight-forward to setup but requires a bit of boilerplate code. It makes use of two mechanisms in Sitecore:
- Event Raising / Handling, which allows you to configure code that subscribes to an event and executes when that event is raised.
- The Event Queue, which allows for events to be raised on one machine and handled by another.
You are able to create your own custom events in Sitecore just by adding them to configuration. First of all, you can define your new event and your cache clearing class in configuration like this:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<event name="dataimport:complete">
<handler type="MyProject.DataImporter.CacheClearer, MyProject.DataImporter" method="ClearCache" />
</event>
<event name="dataimport:complete:remote">
<handler type="MyProject.DataImporter.CacheClearer, MyProject.DataImporter" method="ClearCache" />
</event>
</sitecore>
</configuration>
In this example, I have left out the implementation of MyProject.DataImporter.CacheClearer
, but it is here that you would perform the functionality for clearing your cache.
Once you have this, raising this event can be done through code, which you can do once your import is complete. The following code will raise both the local event as well as the remote one:
// Raise the local event
Event.RaiseEvent("dataimporter:complete");
// Add some data to the Event Queue, which will be consumed by other instances and then raised as events on those instances.
Sitecore.Eventing.EventManager.QueueEvent<DataImportCompleteEvent>(new DataImportCompleteEvent());
In this case, DataImportCompleteEvent
is simply an empty class and used as a means of a class for the remove instance to listen to. You can also use this class and add parameters to it if you want data to be passed to the remote instances as part of the event. I will not add that to this example to keep it simple.
The remote event doesn't fire automatically without further setup. You will also need to write some code that tells each instance to listen out for events of the DataImportCompleteEvent
class and raise the dataimporter:complete:remote
event locally on that machine.
public class DataImportEventHandler
{
public virtual void Initialize(PipelineArgs args)
{
var action = new Action<DataImportCompleteEvent>(RaiseRemoteEvent);
Sitecore.Eventing.EventManager.Subscribe<DataImportCompleteEvent>(action);
}
private void RaiseRemoteEvent(DataImportCompleteEvent myEvent)
{
Sitecore.Events.Event.RaiseEvent("dataimporter:complete:remote");
}
}
To make sure this code is executed at startup, you can add a processor to the initialize pipeline:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<initialize>
<processor type="MyProject.DataImporter.DataImportEventHandler, MyProject" method="Initialize" />
</initialize>
</pipelines>
</sitecore>
</configuration>
The Sitecore community documentation also contains an example that is similar to this, and may provide assistance if you want to add parameters to your event - http://sitecore-community.github.io/docs/pipelines-and-events/events/