Creating custom web farm synchronization tasks

Web farm tasks contain code and synchronization data executed by web farm servers. Create custom web farm tasks if you extended Kentico with functions that work directly with the application’s memory or file storages. For example, if your custom function writes files to the file system and you want these files to be synchronized across all servers in your web farm, you need to write a custom web farm task that handles the synchronization.

You need to have web farms correctly configured and working (have more than one server in the web farm) to implement and test this example.

Registering custom web farm tasks

The following example shows how to create a custom synchronization task that logs information events into the event log of all servers in the web farm environment:

  1. Open your Kentico project in Visual Studio (using the WebSite.sln or WebApp.sln file).

  2. Create a custom class, for example, CustomWebFarmTask, that inherits from WebFarmTaskBase (from the CMS.Core namespace). The class represents the web farm task in the system and encapsulates both its custom synchronization data and execution logic.

  3. Implement the:

    1. ExecuteTask method – contains logic executed on target web farm servers. This method is automatically invoked by target servers when processing the web farm task.

    2. (Optional) Override the virtual ConditionMethod method – contains logic used to evaluate whether the task should be created (when WebFarmHelper.CreateTask is invoked). For example, you may only want to create the task based on the result of a Boolean expression, or the value of a system setting.

      
      
      
       using CMS.Base;
       using CMS.Core;
       using CMS.EventLog;
      
       // Represents the web farm task in the system
       public class CustomWebFarmTask : WebFarmTaskBase
       {
           // Contains the name of the web farm server that created the task
           public string CreatorName { get; set; }
      
           // Holds arbitrary data for processing on target servers
           public object Data { get; set; }
      
           // Contains custom logic to determine whether a new instance of this task should be created whenever WebFarmHelper.CreateTask is invoked
           public override bool ConditionMethod()
           {
               // TODO: Include custom logic that determines whether the task should be created 
      
               return true;
           }   
      
           // Contains logic that is executed when a target server processes the web farm task
           public override void ExecuteTask()
           {
               // Logs a record into the system's event log, with 'Execute' as the event code
               string message = $"Server {SystemContext.ServerName} is processing a task from creator {CreatorName}";
               EventLogProvider.LogInformation("CustomTask", "Execute", message);
      
               // TODO: Include custom logic to be processed by target servers here     
           }   
       }
      
      
       
  4. Create a custom module class.

    • Either add the class into a custom project within the Kentico solution (recommended) or directly into the Kentico web project (into a custom folder under the CMSApp project for web application installations, or the App_Code folder for web site installations).

For execution of initialization code, you only need to register a “code-only” module through the API. You do NOT need to create a new module within the Modules application in the Kentico administration interface.

  1. Override the module’s OnInit method and register the task in the system by calling the WebFarmHelper.RegisterTask method.

    
    
    
     using CMS;
     using CMS.DataEngine;
     using CMS.Helpers;
    
     // Registers the custom module into Kentico
     [assembly: RegisterModule(typeof(CustomWebFarmTaskModule))]
    
     public class CustomWebFarmTaskModule : Module
     {
         // Registers the module in the system under "CustomWebFarmTasks"
         public CustomWebFarmTaskModule()
             : base("CustomWebFarmTasks")
         {
         }
    
         // Contains initialization code that is executed when the application starts
         protected override void OnInit()
         {
             base.OnInit();
    
             // Registers the custom web farm task into the system under the 'CustomWebFarmTask' type
             WebFarmHelper.RegisterTask<CustomWebFarmTask>();
         }
     }
    
    
     
  2. Deploy these code changes to all of your web farm servers. If you are using the MVC development model, this includes the separate MVC application that presents your website.

Each server in the web farm can now process the registered custom tasks.

Creating custom web farm tasks

To create registered web farm tasks, call the WebFarmHelper.CreateTask method (used to create individual web farm tasks from the registered templates) anywhere in your custom code.

If you need to synchronize binary data, for example CRUD operations on custom files present physically on a server’s file system, use WebFarmHelper.CreateIOTask instead.

  1. Write a custom method that handles the web farm task creation, for example:

    
    
    
     using CMS.Base;
     using CMS.EventLog;
     using CMS.Helpers;
    
     ...
    
     // Creates a custom web farm synchronization task of the 'CustomWebFarmTask' type
     public void CreateCustomTask()
     {
         // TODO: Logic that requires synchronization
    
         // Creates the custom web farm synchronization task, saving it to the database for processing by other web farm servers
         WebFarmHelper.CreateTask(new CustomWebFarmTask()
         {
             CreatorName = SystemContext.ServerName,
             Data = null
         });
    
         // Logs a record into the event log of the server that created the web farm task
         string message = $"Server {SystemContext.ServerName} finished processing an operation and created a task for other web farms.";
         EventLogProvider.LogInformation("CustomTask", "Create", message);    
     }
    
    
     
  2. Call the method in your custom code whenever an event that requires synchronization across instances occurs.

The system now creates new web farm tasks of the specified type when the method is invoked. It also logs a record into the event log, with Create as the event code. You can see the logged event in the Event log application.