Graceful handling of task cancellation
This commit is contained in:
parent
5c3a016140
commit
98e0b4ae5f
|
|
@ -172,17 +172,7 @@ public abstract class SendHttpRequestBase : Activity<HttpResponseMessage>
|
|||
/// <inheritdoc />
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var request = PrepareRequest(context);
|
||||
var httpClientFactory = context.GetRequiredService<IHttpClientFactory>();
|
||||
var httpClient = httpClientFactory.CreateClient(nameof(SendHttpRequestBase));
|
||||
var cancellationToken = context.CancellationToken;
|
||||
var response = await httpClient.SendAsync(request, cancellationToken);
|
||||
var parsedContent = await ParseContentAsync(context, response.Content);
|
||||
|
||||
context.Set(Result, response);
|
||||
context.Set(ParsedContent, parsedContent);
|
||||
|
||||
await HandleResponseAsync(context, response);
|
||||
await TrySendAsync(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -190,6 +180,28 @@ public abstract class SendHttpRequestBase : Activity<HttpResponseMessage>
|
|||
/// </summary>
|
||||
protected abstract ValueTask HandleResponseAsync(ActivityExecutionContext context, HttpResponseMessage response);
|
||||
|
||||
private async Task TrySendAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var request = PrepareRequest(context);
|
||||
var httpClientFactory = context.GetRequiredService<IHttpClientFactory>();
|
||||
var httpClient = httpClientFactory.CreateClient(nameof(SendHttpRequestBase));
|
||||
var cancellationToken = context.CancellationToken;
|
||||
|
||||
try
|
||||
{
|
||||
var response = await httpClient.SendAsync(request, cancellationToken);
|
||||
var parsedContent = await ParseContentAsync(context, response.Content);
|
||||
context.Set(Result, response);
|
||||
context.Set(ParsedContent, parsedContent);
|
||||
|
||||
await HandleResponseAsync(context, response);
|
||||
}
|
||||
catch (TaskCanceledException e)
|
||||
{
|
||||
context.JournalData.Add("Cancelled", true);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<object?> ParseContentAsync(ActivityExecutionContext context, HttpContent httpContent)
|
||||
{
|
||||
if (!HasContent(httpContent))
|
||||
|
|
|
|||
|
|
@ -5,13 +5,21 @@ using Elsa.Workflows.Runtime.Notifications;
|
|||
|
||||
namespace Elsa.Http.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// A handler that updates the route table.
|
||||
/// </summary>
|
||||
public class UpdateRouteTable :
|
||||
INotificationHandler<WorkflowTriggersIndexed>,
|
||||
INotificationHandler<WorkflowBookmarksIndexed>
|
||||
{
|
||||
private readonly IRouteTable _routeTable;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpdateRouteTable"/> class.
|
||||
/// </summary>
|
||||
public UpdateRouteTable(IRouteTable routeTable) => _routeTable = routeTable;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task HandleAsync(WorkflowTriggersIndexed notification, CancellationToken cancellationToken)
|
||||
{
|
||||
_routeTable.RemoveRoutes(notification.IndexedWorkflowTriggers.RemovedTriggers);
|
||||
|
|
@ -20,6 +28,7 @@ public class UpdateRouteTable :
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task HandleAsync(WorkflowBookmarksIndexed notification, CancellationToken cancellationToken)
|
||||
{
|
||||
_routeTable.RemoveRoutes(notification.IndexedWorkflowBookmarks.RemovedBookmarks);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Elsa.Workflows.Runtime.Contracts;
|
|||
using Elsa.Workflows.Runtime.Middleware.Activities;
|
||||
using Elsa.Workflows.Runtime.Models;
|
||||
using Elsa.Workflows.Runtime.Models.Requests;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Elsa.Workflows.Runtime.Services;
|
||||
|
||||
|
|
@ -21,6 +22,7 @@ public class DefaultBackgroundActivityInvoker : IBackgroundActivityInvoker
|
|||
private readonly IVariablePersistenceManager _variablePersistenceManager;
|
||||
private readonly IActivityInvoker _activityInvoker;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DefaultBackgroundActivityInvoker"/> class.
|
||||
|
|
@ -32,7 +34,8 @@ public class DefaultBackgroundActivityInvoker : IBackgroundActivityInvoker
|
|||
IWorkflowExecutionContextFactory workflowExecutionContextFactory,
|
||||
IVariablePersistenceManager variablePersistenceManager,
|
||||
IActivityInvoker activityInvoker,
|
||||
IServiceProvider serviceProvider)
|
||||
IServiceProvider serviceProvider,
|
||||
ILogger<DefaultBackgroundActivityInvoker> logger)
|
||||
{
|
||||
_workflowRuntime = workflowRuntime;
|
||||
_workflowDispatcher = workflowDispatcher;
|
||||
|
|
@ -41,6 +44,7 @@ public class DefaultBackgroundActivityInvoker : IBackgroundActivityInvoker
|
|||
_variablePersistenceManager = variablePersistenceManager;
|
||||
_activityInvoker = activityInvoker;
|
||||
_serviceProvider = serviceProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -118,6 +122,12 @@ public class DefaultBackgroundActivityInvoker : IBackgroundActivityInvoker
|
|||
}
|
||||
};
|
||||
|
||||
if(cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
_logger.LogInformation("Background execution for activity {ActivityNodeId} was canceled", activityNodeId);
|
||||
return;
|
||||
}
|
||||
|
||||
await _workflowDispatcher.DispatchAsync(dispatchRequest, cancellationToken);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue