elsa-workflows / elsa-workflows/elsa-core
Cancel background jobs
- Dominant language
- C#
- Stars
- 7.9k
- Forks
- 1.5k
- Avg merge
- 15h 22m
- Merged PRs (30d)
- 114
Description
## Feature Request
### Problem Overview
Cancelling workflow by Elsa Studio or WorkflowExecutionContext.Cancel doesn't cancel CancellationToken in activities with attribute [Activity(Kind = ActivityKind.Job)]
### Proposed Solution
Cancelling workflow by Elsa Studio or WorkflowExecutionContext.Cancel should cancel CancellationToken in all nested activities or workflows.
### Alternative Solutions
I could cancel BackgroundJobs by adding NotificationHandler:
```
public class WorkflowCancelingNotificationHandler : INotificationHandler
{
private readonly IWorkflowRuntime workflowRuntime;
private readonly IBackgroundActivityScheduler backgroundActivityScheduler;
public WorkflowCancelingNotificationHandler(
IWorkflowRuntime workflowRuntime,
IBackgroundActivityScheduler backgroundActivityScheduler)
{
this.workflowRuntime = workflowRuntime;
this.backgroundActivityScheduler = backgroundActivityScheduler;
}
public async Task HandleAsync(WorkflowCancelling notification, CancellationToken cancellationToken)
{
var client = await workflowRuntime.CreateClientAsync(notification.WorkflowInstanceId, cancellationToken);
var workflowState = await client.ExportStateAsync(cancellationToken);
var stimuluses = workflowState.Bookmarks
.Select(b => b.Payload)
.OfType()
.ToList();
foreach (var stimulus in stimuluses)
{
if (string.IsNullOrEmpty(stimulus.JobId))
{
continue;
}
await backgroundActivityScheduler.CancelAsync(stimulus.JobId);
}
}
}
```
WorkflowExecutionContextExtension:
```
public static class WorkflowExecutionContextExtension
{
public static async Task CancelAll(this WorkflowExecutionContext context)
{
var service = context.GetRequiredService();
await service.CancelWorkflowAsync(context.Id);
context.Cancel();
}
}
```
and register it:
```
services.AddNotificationHandler();
```
### Use Cases
It maybe useful to prevent duplicate of long-running jobs, when job must be singleton with timeout. It's not intuitive now, when workflow's sub status is cancelled, but some long task inside activity doesn't.
Contributor guide
Assessment
This issue has not been assessed yet.