Task Scheduler client
The TaskSchedulerClient module allows you to interact with the Task Scheduler cluster.
The elements you can use in this module and its parent module TaskSchedulerShared are described here. It is strongly discouraged to directly use any other elements present in these modules to avoid issues during updates.
User <neos-remote-invoke>
The TaskSchedulerClient module communicates with the Task Scheduler cluster via remote invoke.
These calls are made with a <neos-remote-invoke> user that is automatically created in the Task Scheduler cluster.
Using this particular user avoids giving rights to ordinary users on the Task Scheduler cluster that is single-tenant and sensitive.
The security mode could change in the future but it should remain transparent if you only use the elements provided and listed here.
Required resources association
To use the TaskSchedulerClient module, the following resources must be associated to a function in your cluster:
- Entity view:
KnownIanaTimeZoneView - Entity view:
RemoteScheduledTaskExecutionListView - Entity view:
RemoteScheduledTaskExecutionLogListView - Entity view:
RemoteScheduledTaskListView - UI view:
SchedulerTriggerEditUI - Server method:
CronExpressionToHumanReadableExpression - Server method:
HumanReadableExpressionToCronExpression
These resources are provided by the module and must be properly configured in your permission system to enable task scheduling functionality. They are intentionally not pre-configured to a function, giving you the flexibility to position the function wherever you want in your function tree or to add these resources to an existing function (such as an administration function).
If you display the generic RemoteScheduledTaskListUI administration screen and want its "Enable"/"Disable" and "Modify schedule" row actions to be usable, also associate the following server methods to a function:
- Server method:
SetTaskEnabled - Server method:
UpdateTaskTrigger
Neither action is required for the screen itself (it stays usable read-only): each action is simply hidden for users who cannot call the corresponding server method, so leaving these two unassociated keeps the screen strictly read-only + delete.
Exposed server methods
ScheduleTask
This method makes a remote invoke call to schedule a new task.
It expects a parameter of type GroupeIsa.Neos.TaskScheduler.Application.Abstractions.DataObjects.RemoteScheduledTask describing the scheduled task.
On the UI side, the Trigger property can be set by the user using NavigateToTriggerEditUIAsync.
Example of a call inspired by the NeosCommunity cluster:
try
{
SchedulerTriggerProperties triggerProperties = ...
RemoteScheduledTask task = new()
{
Trigger = triggerProperties,
ErrorMessage = null,
Enabled = true,
Id = Guid.NewGuid(),
RunAs = null,
ServerMethodName = nameof(Synchronize),
Description = "Discourse synchronization",
};
await _scheduleTask.ExecuteAsync(task, cancellationToken);
}
catch (HttpRequestException ex)
{
throw new BusinessException("Unable to contact the scheduling service or error in the processing initiated.", ex);
}
UnscheduleTask
This method makes a remote invoke call to delete a scheduled task. It expects the scheduled task identifier as a parameter.
Example of a call inspired by the Saving of RemoteScheduledTaskListView:
public class Saving : ISavingRule<IMyEntityView>
{
private readonly IUnscheduleTask _unscheduleTask;
public Saving(IUnscheduleTask unscheduleTask)
{
_unscheduleTask = unscheduleTask;
}
public async Task OnSavingAsync(ISavingRuleArguments<IMyEntityView> args, CancellationToken cancellationToken)
{
foreach (IRemoteScheduledTaskListView item in args.DeletedItems)
{
if (item.ReadOnly)
{
throw new NotSupportedException();
}
await _unscheduleTask.ExecuteAsync(item.Id, cancellationToken);
}
}
}
UpdateTask
This method makes a remote invoke call to update an existing scheduled task (cron, dates, timezone, description, arguments, RunAs, Enabled, Timeout, StartupTimeout) without changing its Id.
It expects a complete RemoteScheduledTask (the same shape as ScheduleTask), including its RowVersion for optimistic concurrency: Neos rejects the update if the task was modified since it was last read, instead of silently overwriting it. There is no partial update: to change a single field, first reread the task via GetScheduledTasks, modify only the field you need, then send the complete object (with its RowVersion) back to UpdateTask.
IPagedList<RemoteScheduledTask> tasks = await _getScheduledTasks.ExecuteAsync(
filter: $"Id eq {taskId}", skip: 0, top: 1, cancellationToken: cancellationToken);
RemoteScheduledTask task = tasks.Single();
task.Trigger.CronStringExpression = newCronExpression;
await _updateTask.ExecuteAsync(task, cancellationToken);
GetScheduledTasks
This method makes a remote invoke call to retrieve the scheduled tasks of the running cluster.
If the cluster is multi-tenant, the tasks returned are those common to all tenants (read-only) and those specific to the tenant.
Filtering and sorting are expected in OData syntax (you can consult the GroupeIsa.Neos.TaskScheduler.TaskSchedulerClient.Application.Methods.GetScheduledTasks.Response class to get the list of accessible properties).
Example of a call inspired by the Retrieving of RemoteScheduledTaskListView:
public class Retrieving : IRetrievingRule<IMyEntityView>
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IGetScheduledTasks _getScheduledTasks;
public Retrieving(
IHttpContextAccessor httpContextAccessor,
IGetScheduledTasks getScheduledTasks)
{
_httpContextAccessor = httpContextAccessor;
_getScheduledTasks = getScheduledTasks;
}
public async Task OnRetrievingAsync(IRetrievingRuleArguments<IMyEntityView> args, CancellationToken cancellationToken)
{
IPagedList<RemoteScheduledTask> tasks;
if (args.Key != null)
{
tasks = await _getScheduledTasks.ExecuteAsync(
filter: $"Id eq {args.Key}", skip: 0, top: 1, cancellationToken: cancellationToken);
}
else
{
HttpContext? context = _httpContextAccessor.HttpContext;
string? filter = context?.Request.Query["$filter"];
string? orderBy = context?.Request.Query["$orderby"];
tasks = await _getScheduledTasks.ExecuteAsync(
filter: filter, orderBy: orderBy, skip: args.Skip, top: args.Top, cancellationToken: cancellationToken);
}
...
}
}
GetScheduledTaskExecutions
This method makes a remote invoke call to retrieve the scheduled task executions of the running cluster.
If the cluster is multi-tenant, the executions returned are only those of the current tenant.
The filter and sort are expected in OData syntax (you can consult the GroupeIsa.Neos.TaskScheduler.TaskSchedulerClient.Application.Methods.GetScheduledTaskExecutions.Response class to get the list of accessible properties).
Example of a call inspired by the Retrieving of RemoteScheduledTaskExecutionListView:
public class Retrieving : IRetrievingRule<IMyEntityView>
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IGetScheduledTaskExecutions _getScheduledTaskExecutions;
public Retrieving(
IHttpContextAccessor httpContextAccessor,
IGetScheduledTaskExecutions getScheduledTaskExecutions)
{
_httpContextAccessor = httpContextAccessor;
_getScheduledTaskExecutions = getScheduledTaskExecutions;
}
public async Task OnRetrievingAsync(IRetrievingRuleArguments<IMyEntityView> args, CancellationToken cancellationToken)
{
IPagedList<RemoteScheduledTaskExecution> executions;
if (args.Key != null)
{
executions = await _getScheduledTaskExecutions.ExecuteAsync(
filter: $"Id eq {args.Key}", skip: 0, top: 1, cancellationToken: cancellationToken);
}
else
{
HttpContext? context = _httpContextAccessor.HttpContext;
string? filter = context?.Request.Query["$filter"];
string? orderBy = context?.Request.Query["$orderby"];
executions = await _getScheduledTaskExecutions.ExecuteAsync(
filter: filter, orderBy: orderBy, skip: args.Skip, top: args.Top, cancellationToken: cancellationToken);
}
...
}
}
GetScheduledTaskExecutionLogs
This method makes a remote invoke call to retrieve the logs of a given execution.
Example of a call inspired by the Retrieving of RemoteScheduledTaskExecutionLogListView:
public class Retrieving : IRetrievingRule<IMyEntityView>
{
private readonly IGetScheduledTaskExecutionLogs _getScheduledTaskExecutionLogs;
public Retrieving(IGetScheduledTaskExecutionLogs getScheduledTaskExecutionLogs)
{
_getScheduledTaskExecutionLogs = getScheduledTaskExecutionLogs;
}
public async Task OnRetrievingAsync(IRetrievingRuleArguments<IMyEntityView> args, CancellationToken cancellationToken)
{
IPagedList<RemoteScheduledTaskExecutionLog> logs;
if (args.Key != null)
{
throw new NotSupportedException();
}
else
{
logs = await _getScheduledTaskExecutionLogs.ExecuteAsync(
args.Parameters.GetScheduledTaskExecutionId(), cancellationToken);
}
...
}
}
Exposed UI methods
SchedulerHelpers.NavigateToTriggerEditUIAsync
This method displays the screen for entering the trigger conditions for a scheduled task. The first parameter gives the initial values of the properties and the second is a callback called if the user validates his entry:
Example inspired by the NeosCommunity cluster:
await UIMethods.SchedulerHelpers.NavigateToTriggerEditUIAsync(
new SchedulerTriggerProperties(),
async t =>
{
// Calling a server process to create a scheduled task from the entered trigger properties
await ServerMethods.ScheduleSynchronization.ExecuteAsync(t);
await LoadDataAsync();
}
);
Exposed UI views
RemoteScheduledTaskListUI
You can launch this UI to display all scheduled tasks of the cluster. This is a generic administration UI. If it does not meet your needs, we advise you to create your own UI rather than overloading this one. The data displayed is the one returned by GetScheduledTasks.
The row menu also offers "Enable"/"Disable" and "Modify schedule" actions. They call the exposed SetTaskEnabled and UpdateTaskTrigger server methods, which internally reread the task and call UpdateTask with the requested change. RemoteScheduledTaskListView itself is not updatable: these actions never touch it directly, they only call the two server methods above. Each action is hidden whenever the corresponding server method is not associated to a function or the current user lacks the permission.
RemoteScheduledTaskExecutionListUI
You can launch this UI to display all scheduled task executions. This is a generic administration UI. If it does not meet your needs, we recommend you to create your own UI rather than overloading this one. The data displayed is the one returned by GetScheduledTaskExecutions.
RemoteScheduledTaskExecutionDetailsUI
This UI is used internally by RemoteScheduledTaskExecutionListUI to display the details of an execution. It is normally not necessary to use it directly. The data displayed is the one returned by GetScheduledTaskExecutionLogs.