Every so often, it may be useful to trigger code execution on a remote server from a local server. Thankfully, Sitecore has a concept for this- Events. There are two distinct pieces that make up “Events”: Remote Events and local events. The community docs on GitHub has a great overview of the differences between local and Remote events. At face value, the two event concepts are unrelated, however, they are often linked together. I was able to find one example detailing how Remote Events and local events can be utilized to trigger code from one server to execute code on all remote servers. In a recent deep-dive, I found that Sitecore has a few built-in features to make this slightly easier than the existing post. The technique is outlined below.
Create Remote Event Object Class to Pass Data Between Servers
There are two important pieces of this class:
- It implements
IHasEventName. This will make it easier to execute the local code later on.
- Notice the
DataMemberattributes. An instance of this class will ultimately be serialized into the EventQueue database table and thus the class must be serializable. This class should contain the data that you wish to pass between servers. In this example, I will be sending the
InstanceNameof the server that triggered the event.
- Note: This is only an example. The InstanceName is already included with any Remote Event added to the EventQueue. Use your imagination/requirements to determine what else could be passed between servers.
Subscribe to Remote Event and Setup Local Event Trigger
This code accomplishes two things:
- Upon site initialization it instructs Sitecore to add a remote event subscriber to watch for an object of type
LogMessageRemoteEventadded to the EventQueue
- Links the execution of the Remote Event with the raising of a local event. This executes the local
EventNameand runs all handlers associated with it on the remote server (the server that the EventQueue is executing from at the time)
Specify the Code To Execute on Remote Servers
This code reads the
InstanceName of the calling server and logs it to the local logs of the remote server. The
InstanceName is passed between servers via the EventQueue.
Trigger the Remote Event
This code can be executed anywhere within Sitecore. It adds an object to the EventQueue that will be picked up on each server individually as they process the EventQueue. By default, this is every 2 seconds.
Notice the same serialized event object (
LogMessageRemoteEvent) could be passed to different local events because the local
eventName is a parameter. Continuing this example, instead of logging the
InstanceName of the calling server on each remote server, you could have each remote server phone-home to the calling server with some type of health status.
One thing that may not be obvious with this type of an implementation is that it does not require any special config transformations. All servers that use the same EventQueue (the same cluster) all use the same config files. The EventQueue orchestrates which servers run the code and which do not via the
runGlobal flags. In this example, all servers EXCEPT the calling server will log the message.
The brains of this post were delicately pulled from
Sitecore.Eventing.Remote.RemoteEventMap. This post would be been a few lines shorter had the method
Sitecore.Eventing.Remote.RemoteEventMap :: OnGenericRemoteEvent been
public instead of