Create an agent
You can create an agent that inherits BaseAgent
or RecurringAgent
, and you can choose whether or not the agent should scale. Reasons to create a custom agent include:
Perform regularly scheduled maintenance within the engine, such as purging expired data from a database that the engine relies on. By default, the Processing Engine includes two agents that perform maintenance tasks.
Note
It is rare that you will need to create a custom agent. It is more likely that you will create a custom processing worker that will be executed by the default TaskAgent
.
Create an agent that inherits RecurringAgent
The following sample agent calls a method that cleans up data in a fake storage provider. The storage provider is represented by the ICustomProvider
interface. The agent inherits RecurringAgent
, which means it will run at regular, configurable intervals.
Create an agent class
To create the agent class:
Create a class and copy the following sample agent.
Note
The sample ICustomProvider
and CustomProvider
classes are included in the same file for convenience.
using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Sitecore.Framework.Conditions; using Sitecore.Processing.Engine.Abstractions; using Sitecore.Processing.Engine.Agents; namespace Sitecore.Documentation.Examples { /// <summary> /// Provides basic agent functionality and services. /// </summary> public class SampleCleanupAgent : RecurringAgent { private readonly ICustomProvider _customProvider; /// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="options"></param> /// <param name="customProvider"></param> protected SampleCleanupAgent(ILogger<IAgent> logger, IConfiguration options, ICustomProvider customProvider) : base(options, logger) { Condition.Requires(customProvider, nameof(customProvider)).IsNotNull(); _customProvider = customProvider; } /// <summary> /// /// </summary> /// <param name="token"></param> /// <returns></returns> protected override async Task RecurringExecuteAsync(CancellationToken token) { // Checks if cancellation has been requested in case task is long-running // It is your responsibility to check the status of the cancellation token while (!token.IsCancellationRequested) { await _customProvider.CleanData().ConfigureAwait(false); } } } /// <summary> /// /// </summary> public interface ICustomProvider { /// <summary> /// /// </summary> /// <returns></returns> Task GetData(); /// <summary> /// /// </summary> /// <returns></returns> Task CleanData(); } /// <summary> /// /// </summary> public class CustomProvider : ICustomProvider { /// <summary> /// /// </summary> /// <returns></returns> public async Task CleanData() { // Clean up data in custom data provider await Task.Delay(1).ConfigureAwait(false); } /// <summary> /// /// </summary> /// <returns></returns> public async Task GetData() { // Get data from custom data provider await Task.Delay(1).ConfigureAwait(false); } } }
Register agent and services in configuration
Create a file named sc.Processing.Engine.CustomAgents.xml in <engine-root>\\App_Data\\Config\\Global.
Register
SampleCleanupAgent
andICustomProvider
as shown. This example uses simple configuration to register a single agent.
<Settings> <Sitecore> <Processing> <Services> <ICustomProvider> <Type>Sitecore.Documentation.Examples.CustomProvider, Sitecore.Documentation.Examples</Type> <As>Sitecore.Documentation.Examples.ICustomProvider, Sitecore.Documentation.Examples</As> <LifeTime>Transient</LifeTime> </ICustomProvider> <SampleCleanupAgent> <Type>Sitecore.Documentation.Examples.SampleCleanupAgent, Sitecore.Documentation.Examples</Type> <As>Sitecore.Processing.Engine.Abstractions.IAgent, Sitecore.Processing.Engine.Abstractions</As> <LifeTime>Transient</LifeTime> <Options> <!-- The period which the agent sleeps before running again. --> <SleepPeriod>0.00:00:14.000</SleepPeriod> </Options> </SampleCleanupAgent> </Services> </Processing> </Sitecore> </Settings>
Alternatively, if the agent needs to scale, use ParallelAgentsConfiguration
to register it:
<Settings> <Sitecore> <Processing> <Services> <ICustomProvider> <Type>Sitecore.Documentation.Examples.CustomProvider, Sitecore.Documentation.Examples</Type> <As>Sitecore.Documentation.Examples.ICustomProvider, Sitecore.Documentation.Examples</As> <LifeTime>Transient</LifeTime> </ICustomProvider> <SampleCleanupAgent> <Type>Sitecore.Processing.Engine.Agents.ParallelAgentsConfiguration, Sitecore.Processing.Engine</Type> <As>Sitecore.XConnect.DependencyInjection.Abstractions.IXConnectServicesConfiguration, Sitecore.XConnect.DependencyInjection</As> <LifeTime>Transient</LifeTime> <Options> <AgentFixedCount>0</AgentFixedCount> <AgentCoreRatio>0.75</AgentCoreRatio> <AgentConfiguration> <Type>Sitecore.Documentation.Examples.SampleCleanupAgent, Sitecore.Documentation.Examples</Type> <As>Sitecore.Processing.Engine.Abstractions.IAgent, Sitecore.Processing.Engine.Abstractions</As> <LifeTime>Transient</LifeTime> <Options> <SleepPeriod>0.00:00:14.000</SleepPeriod> </Options> </AgentConfiguration> </Options> </SampleCleanupAgent> </Services> </Processing> </Sitecore> </Settings>
Create an agent that inherits BaseAgent
The following sample agent writes a message to the log on startup and waits 1 millisecond. The agent does not inherit RecurringAgent
and will not run at regular intervals.
Important
This particular agent runs once on engine startup. However, your agent might sleep until a particular event occurs, then sleep again until the event happens again. The agent does technically 'recur', but not at regularly scheduled intervals.
Create an agent class
To create an agent class:
Create a class and copy the following sample agent.
using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Sitecore.Processing.Engine.Abstractions; using Sitecore.Processing.Engine.Agents; namespace Sitecore.Documentation.Examples { /// <summary> /// Provides basic agent functionality and services. /// </summary> public class SampleLogAgent : BaseAgent { /// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="options"></param> protected SampleLogAgent(ILogger<IAgent> logger, IConfiguration options) : base(logger, options) { } /// <summary> /// /// </summary> /// <param name="token"></param> /// <returns></returns> public override async Task ExecuteAsync(CancellationToken token) { // Write a custom log message // No cancellation token check in this example as task is unlikely to be long-running base.Log.LogInformation("Your custom agent has started."); await Task.Delay(1).ConfigureAwait(false); } } }
Register agent in configuration
Create a file named sc.Processing.Engine.CustomAgents.xml in <engine-root>\\App_Data\\Config\\Global.
Register
SampleCleanupAgent
as shown. This example uses simple configuration to register a single agent.<Settings> <Sitecore> <Processing> <Services> <SampleLogAgent> <Type>Sitecore.Documentation.Examples.SampleLogAgent, Sitecore.Documentation.Examples</Type> <As>Sitecore.Processing.Engine.Abstractions.IAgent, Sitecore.Processing.Engine.Abstractions</As> <LifeTime>Transient</LifeTime> </SampleLogAgent> </Services> </Processing> </Sitecore> </Settings>
Task cancellation
All If you implement an agent that may result in a long-running task, make sure that you check token.IsCancellationRequested
property in the ExecuteAsync
method (for agents inheriting BaseAgent
) or the RecurringExecuteAsync
method (agents inheriting RecurringAgent
).