diff --git a/src/modules/Elsa.MassTransit/Consumers/DispatchWorkflowRequestConsumer.cs b/src/modules/Elsa.MassTransit/Consumers/DispatchWorkflowRequestConsumer.cs
index 3361b4eb9..7592d9d21 100644
--- a/src/modules/Elsa.MassTransit/Consumers/DispatchWorkflowRequestConsumer.cs
+++ b/src/modules/Elsa.MassTransit/Consumers/DispatchWorkflowRequestConsumer.cs
@@ -7,9 +7,9 @@ namespace Elsa.MassTransit.Consumers;
///
/// A consumer of various dispatch message types to asynchronously execute workflows.
///
-public class DispatchWorkflowRequestConsumer :
- IConsumer,
- IConsumer,
+public class DispatchWorkflowRequestConsumer :
+ IConsumer,
+ IConsumer,
IConsumer,
IConsumer
{
@@ -28,7 +28,7 @@ public class DispatchWorkflowRequestConsumer :
{
var message = context.Message;
var options = new StartWorkflowRuntimeOptions(message.CorrelationId, message.Input, message.VersionOptions, InstanceId: message.InstanceId);
-
+
await _workflowRuntime.StartWorkflowAsync(message.DefinitionId, options, context.CancellationToken);
}
@@ -36,7 +36,17 @@ public class DispatchWorkflowRequestConsumer :
public async Task Consume(ConsumeContext context)
{
var message = context.Message;
- var options = new ResumeWorkflowRuntimeOptions(message.CorrelationId, message.InstanceId, message.BookmarkId, message.ActivityId, message.Input);
+
+ var options = new ResumeWorkflowRuntimeOptions(
+ message.CorrelationId,
+ message.InstanceId,
+ message.BookmarkId,
+ message.ActivityId,
+ message.ActivityNodeId,
+ message.ActivityInstanceId,
+ message.ActivityHash,
+ message.Input);
+
await _workflowRuntime.ResumeWorkflowAsync(message.InstanceId, options, context.CancellationToken);
}
diff --git a/src/modules/Elsa.MassTransit/Implementations/MassTransitWorkflowDispatcher.cs b/src/modules/Elsa.MassTransit/Implementations/MassTransitWorkflowDispatcher.cs
index ff4db4690..413ba00ad 100644
--- a/src/modules/Elsa.MassTransit/Implementations/MassTransitWorkflowDispatcher.cs
+++ b/src/modules/Elsa.MassTransit/Implementations/MassTransitWorkflowDispatcher.cs
@@ -40,6 +40,9 @@ public class MassTransitWorkflowDispatcher : IWorkflowDispatcher
request.InstanceId,
request.BookmarkId,
request.ActivityId,
+ request.ActivityNodeId,
+ request.ActivityInstanceId,
+ request.ActivityHash,
request.Input,
request.CorrelationId
), cancellationToken);
diff --git a/src/modules/Elsa.MassTransit/Messages/DispatchWorkflowInstance.cs b/src/modules/Elsa.MassTransit/Messages/DispatchWorkflowInstance.cs
index db67e0d52..5e83a0d84 100644
--- a/src/modules/Elsa.MassTransit/Messages/DispatchWorkflowInstance.cs
+++ b/src/modules/Elsa.MassTransit/Messages/DispatchWorkflowInstance.cs
@@ -5,6 +5,9 @@ public record DispatchWorkflowInstance
string InstanceId,
string? BookmarkId,
string? ActivityId,
+ string? ActivityNodeId,
+ string? ActivityInstanceId,
+ string? ActivityHash,
IDictionary? Input,
string? CorrelationId
);
\ No newline at end of file
diff --git a/src/modules/Elsa.ProtoActor/Grains/WorkflowGrain.cs b/src/modules/Elsa.ProtoActor/Grains/WorkflowGrain.cs
index f66cba85c..f6be977a9 100644
--- a/src/modules/Elsa.ProtoActor/Grains/WorkflowGrain.cs
+++ b/src/modules/Elsa.ProtoActor/Grains/WorkflowGrain.cs
@@ -146,8 +146,20 @@ public class WorkflowGrain : WorkflowGrainBase
var correlationId = request.CorrelationId;
var bookmarkId = request.BookmarkId.NullIfEmpty();
var activityId = request.ActivityId.NullIfEmpty();
+ var activityNodeId = request.ActivityNodeId.NullIfEmpty();
+ var activityInstanceId = request.ActivityInstanceId.NullIfEmpty();
+ var activityHash = request.ActivityHash.NullIfEmpty();
var cancellationToken = Context.CancellationToken;
- var resumeWorkflowHostOptions = new ResumeWorkflowHostOptions(correlationId, bookmarkId, activityId, _input);
+
+ var resumeWorkflowHostOptions = new ResumeWorkflowHostOptions(
+ correlationId,
+ bookmarkId,
+ activityId,
+ activityNodeId,
+ activityInstanceId,
+ activityHash,
+ _input);
+
var definitionId = _definitionId;
var versionOptions = VersionOptions.SpecificVersion(_version);
diff --git a/src/modules/Elsa.ProtoActor/Protos/Messages.proto b/src/modules/Elsa.ProtoActor/Protos/Messages.proto
index 06156ab3c..53e52efa3 100644
--- a/src/modules/Elsa.ProtoActor/Protos/Messages.proto
+++ b/src/modules/Elsa.ProtoActor/Protos/Messages.proto
@@ -37,7 +37,10 @@ message ResumeWorkflowRequest {
optional string CorrelationId = 2;
optional string BookmarkId = 3;
optional string ActivityId = 4;
- optional Input input = 5;
+ optional string ActivityNodeId = 5;
+ optional string ActivityInstanceId = 6;
+ optional string ActivityHash = 7;
+ optional Input input = 8;
}
message ResumeWorkflowResponse {
diff --git a/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowRunner.cs b/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowRunner.cs
index 874dd78b4..60f2f4da7 100644
--- a/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowRunner.cs
+++ b/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowRunner.cs
@@ -23,6 +23,9 @@ public record RunWorkflowOptions(
string? InstanceId = default,
string? CorrelationId = default,
string? BookmarkId = default,
- string? ActivityNodeId = default,
+ string? ActivityId = default,
+ string? ActivityNodeId = default,
+ string? ActivityInstanceId = default,
+ string? ActivityHash = default,
IDictionary? Input = default,
string? TriggerActivityId = default);
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Extensions/WorkflowExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/WorkflowExecutionContextExtensions.cs
index de3bac037..7f480bb41 100644
--- a/src/modules/Elsa.Workflows.Core/Extensions/WorkflowExecutionContextExtensions.cs
+++ b/src/modules/Elsa.Workflows.Core/Extensions/WorkflowExecutionContextExtensions.cs
@@ -54,6 +54,16 @@ public static class WorkflowExecutionContextExtensions
var workItem = new ActivityWorkItem(activity.Id, async () => await activityInvoker.InvokeAsync(workflowExecutionContext, activity));
workflowExecutionContext.Scheduler.Schedule(workItem);
}
+
+ ///
+ /// Schedules the specified activity execution context of the workflow.
+ ///
+ public static void ScheduleActivityExecutionContext(this WorkflowExecutionContext workflowExecutionContext, ActivityExecutionContext activityExecutionContext)
+ {
+ var activityInvoker = workflowExecutionContext.GetRequiredService();
+ var workItem = new ActivityWorkItem(activityExecutionContext.Activity.Id, async () => await activityInvoker.InvokeAsync(activityExecutionContext));
+ workflowExecutionContext.Scheduler.Schedule(workItem);
+ }
///
/// Schedules the activity of the specified bookmark.
diff --git a/src/modules/Elsa.Workflows.Core/Models/WorkflowExecutionContext.cs b/src/modules/Elsa.Workflows.Core/Models/WorkflowExecutionContext.cs
index acc183596..5df4ea903 100644
--- a/src/modules/Elsa.Workflows.Core/Models/WorkflowExecutionContext.cs
+++ b/src/modules/Elsa.Workflows.Core/Models/WorkflowExecutionContext.cs
@@ -23,6 +23,7 @@ public class WorkflowExecutionContext : IExecutionContext
{
internal static ValueTask Complete(ActivityExecutionContext context) => context.CompleteActivityAsync();
private readonly IServiceProvider _serviceProvider;
+ private readonly IHasher _hasher;
private readonly IActivityRegistry _activityRegistry;
private readonly IList _nodes;
private readonly IList _completionCallbackEntries = new List();
@@ -33,6 +34,7 @@ public class WorkflowExecutionContext : IExecutionContext
///
public WorkflowExecutionContext(
IServiceProvider serviceProvider,
+ IHasher hasher,
string id,
string? correlationId,
Workflow workflow,
@@ -47,6 +49,7 @@ public class WorkflowExecutionContext : IExecutionContext
CancellationToken cancellationToken)
{
_serviceProvider = serviceProvider;
+ _hasher = hasher;
_activityRegistry = activityRegistry;
Workflow = workflow;
Graph = graph;
@@ -61,6 +64,7 @@ public class WorkflowExecutionContext : IExecutionContext
TriggerActivityId = triggerActivityId;
CancellationToken = cancellationToken;
NodeIdLookup = _nodes.ToDictionary(x => x.NodeId);
+ NodeHashLookup = _nodes.ToDictionary(x => Hash(x.NodeId));
NodeActivityLookup = _nodes.ToDictionary(x => x.Activity);
MemoryRegister = workflow.CreateRegister();
ExpressionExecutionContext = new ExpressionExecutionContext(serviceProvider, MemoryRegister, cancellationToken: cancellationToken);
@@ -110,6 +114,11 @@ public class WorkflowExecutionContext : IExecutionContext
/// A map between activity IDs and s in the workflow graph.
///
public IDictionary NodeIdLookup { get; }
+
+ ///
+ /// A map between hashed activity node IDs and s in the workflow graph.
+ ///
+ public IDictionary NodeHashLookup { get; }
///
/// A map between s and s in the workflow graph.
@@ -267,6 +276,13 @@ public class WorkflowExecutionContext : IExecutionContext
/// Returns the with the specified activity ID from the workflow graph.
///
public ActivityNode FindNodeById(string nodeId) => NodeIdLookup[nodeId];
+
+ ///
+ /// Returns the with the specified hash of the activity node ID from the workflow graph.
+ ///
+ /// The hash of the activity node ID.
+ /// The with the specified hash of the activity node ID.
+ public ActivityNode FindNodeByHash(string hash) => NodeHashLookup[hash];
///
/// Returns the containing the specified activity from the workflow graph.
@@ -279,11 +295,16 @@ public class WorkflowExecutionContext : IExecutionContext
public IActivity FindActivityByNodeId(string nodeId) => FindNodeById(nodeId).Activity;
///
- ///
+ /// Returns the with the specified ID from the workflow graph.
///
- ///
- ///
public IActivity FindActivityByActivityId(string activityId) => FindNodeById(NodeIdLookup.Single(n => n.Key.Contains(activityId)).Value.NodeId).Activity;
+
+ ///
+ /// Returns the with the specified hash of the activity node ID from the workflow graph.
+ ///
+ /// The hash of the activity node ID.
+ /// The with the specified hash of the activity node ID.
+ public IActivity FindActivityByHash(string hash) => FindNodeByHash(hash).Activity;
///
/// Returns a custom property with the specified key from the dictionary.
@@ -311,12 +332,12 @@ public class WorkflowExecutionContext : IExecutionContext
///
public bool HasProperty(string name) => Properties.ContainsKey(name);
+ internal bool CanTransitionTo(WorkflowSubStatus targetSubStatus) => ValidateStatusTransition(targetSubStatus);
+
internal void TransitionTo(WorkflowSubStatus subStatus)
{
- var targetStatus = GetMainStatus(subStatus);
-
- if (!ValidateStatusTransition(SubStatus, subStatus))
- throw new Exception($"Cannot transition from {Status} to {targetStatus}");
+ if (!ValidateStatusTransition(SubStatus))
+ throw new Exception($"Cannot transition from {SubStatus} to {subStatus}");
SubStatus = subStatus;
}
@@ -390,11 +411,11 @@ public class WorkflowExecutionContext : IExecutionContext
_ => throw new ArgumentOutOfRangeException(nameof(subStatus), subStatus, null)
};
- private bool ValidateStatusTransition(WorkflowSubStatus currentSubStatus, WorkflowSubStatus target)
+ private bool ValidateStatusTransition(WorkflowSubStatus targetSubStatus)
{
- var currentMainStatus = GetMainStatus(currentSubStatus);
+ var currentMainStatus = GetMainStatus(SubStatus);
return currentMainStatus != WorkflowStatus.Finished;
}
- private IEnumerable GetMergedRegistersView() => new[] { MemoryRegister }.Concat(ActivityExecutionContexts.Select(x => x.ExpressionExecutionContext.Memory)).ToList();
+ private string Hash(string nodeId) => _hasher.Hash(nodeId);
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Services/DefaultWorkflowExecutionContextFactory.cs b/src/modules/Elsa.Workflows.Core/Services/DefaultWorkflowExecutionContextFactory.cs
index 184f36783..19cb5be80 100644
--- a/src/modules/Elsa.Workflows.Core/Services/DefaultWorkflowExecutionContextFactory.cs
+++ b/src/modules/Elsa.Workflows.Core/Services/DefaultWorkflowExecutionContextFactory.cs
@@ -13,6 +13,7 @@ public class DefaultWorkflowExecutionContextFactory : IWorkflowExecutionContextF
private readonly IActivitySchedulerFactory _schedulerFactory;
private readonly IActivityRegistry _activityRegistry;
private readonly IWorkflowStateSerializer _workflowStateSerializer;
+ private readonly IHasher _hasher;
///
/// Constructor.
@@ -22,13 +23,15 @@ public class DefaultWorkflowExecutionContextFactory : IWorkflowExecutionContextF
IIdentityGraphService identityGraphService,
IActivitySchedulerFactory schedulerFactory,
IActivityRegistry activityRegistry,
- IWorkflowStateSerializer workflowStateSerializer)
+ IWorkflowStateSerializer workflowStateSerializer,
+ IHasher hasher)
{
_activityVisitor = activityVisitor;
_identityGraphService = identityGraphService;
_schedulerFactory = schedulerFactory;
_activityRegistry = activityRegistry;
_workflowStateSerializer = workflowStateSerializer;
+ _hasher = hasher;
}
///
@@ -64,6 +67,7 @@ public class DefaultWorkflowExecutionContextFactory : IWorkflowExecutionContextF
// Setup a workflow execution context.
var workflowExecutionContext = new WorkflowExecutionContext(
serviceProvider,
+ _hasher,
instanceId,
correlationId,
workflow,
diff --git a/src/modules/Elsa.Workflows.Core/Services/Hasher.cs b/src/modules/Elsa.Workflows.Core/Services/Hasher.cs
index 14fd9e40b..7b3d01247 100644
--- a/src/modules/Elsa.Workflows.Core/Services/Hasher.cs
+++ b/src/modules/Elsa.Workflows.Core/Services/Hasher.cs
@@ -10,7 +10,7 @@ public class Hasher : IHasher
///
public string Hash(string value)
{
- using var sha = HashAlgorithm.Create(HashAlgorithmName.SHA256.ToString())!;
+ using var sha = SHA256.Create();
return Hash(sha, value);
}
diff --git a/src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs b/src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs
index 516408732..fb9f63f08 100644
--- a/src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs
+++ b/src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs
@@ -114,7 +114,10 @@ public class WorkflowRunner : IWorkflowRunner
var triggerActivityId = options?.TriggerActivityId;
var workflowExecutionContext = await CreateWorkflowExecutionContextAsync(scope.ServiceProvider, workflow, workflowState.Id, correlationId, workflowState, input, default, triggerActivityId, cancellationToken);
var bookmarkId = options?.BookmarkId;
- var nodeId = options?.ActivityNodeId;
+ var activityNodeId = options?.ActivityNodeId;
+ var activityId = options?.ActivityId;
+ var activityInstanceId = options?.ActivityInstanceId;
+ var activityHash = options?.ActivityHash;
if (bookmarkId != null)
{
@@ -124,12 +127,30 @@ public class WorkflowRunner : IWorkflowRunner
if (bookmark != null)
workflowExecutionContext.ScheduleBookmark(bookmark);
}
- else if (nodeId != null)
+ else if (activityNodeId != null)
{
// Schedule the activity.
- var activity = workflowExecutionContext.FindActivityByNodeId(nodeId);
+ var activity = workflowExecutionContext.FindActivityByNodeId(activityNodeId);
workflowExecutionContext.ScheduleActivity(activity);
}
+ else if (activityHash != null)
+ {
+ // Schedule the activity.
+ var activity = workflowExecutionContext.FindActivityByHash(activityHash);
+ workflowExecutionContext.ScheduleActivity(activity);
+ }
+ else if (activityId != null)
+ {
+ // Schedule the activity.
+ var activity = workflowExecutionContext.FindActivityByActivityId(activityId);
+ workflowExecutionContext.ScheduleActivity(activity);
+ }
+ else if (activityInstanceId != null)
+ {
+ // Schedule the activity.
+ var activityExecutionContext = workflowExecutionContext.ActivityExecutionContexts.FirstOrDefault(x => x.Id == activityInstanceId) ?? throw new Exception("No activity execution context found with the specified ID.");
+ workflowExecutionContext.ScheduleActivityExecutionContext(activityExecutionContext);
+ }
else
{
// Schedule the workflow itself.
diff --git a/src/modules/Elsa.Workflows.Runtime/Commands/DispatchWorkflowInstanceCommand.cs b/src/modules/Elsa.Workflows.Runtime/Commands/DispatchWorkflowInstanceCommand.cs
index c138cb105..d77543a81 100644
--- a/src/modules/Elsa.Workflows.Runtime/Commands/DispatchWorkflowInstanceCommand.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Commands/DispatchWorkflowInstanceCommand.cs
@@ -8,5 +8,8 @@ public record DispatchWorkflowInstanceCommand(
string InstanceId,
string? BookmarkId = default,
string? ActivityId = default,
+ string? ActivityNodeId = default,
+ string? ActivityInstanceId = default,
+ string? ActivityHash = default,
IDictionary? Input = default,
string? CorrelationId = default) : ICommand;
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowHost.cs b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowHost.cs
index b54376422..f38e047d8 100644
--- a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowHost.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowHost.cs
@@ -13,22 +13,22 @@ public interface IWorkflowHost
/// The workflow definition.
///
Workflow Workflow { get; set; }
-
+
///
/// The workflow state.
///
WorkflowState WorkflowState { get; set; }
-
+
///
/// Returns a value indicating whether or not the specified workflow can start a new instance or not.
///
Task CanStartWorkflowAsync(StartWorkflowHostOptions? options = default, CancellationToken cancellationToken = default);
-
+
///
/// Start a new workflow instance and execute it.
///
Task StartWorkflowAsync(StartWorkflowHostOptions? options = default, CancellationToken cancellationToken = default);
-
+
///
/// Resume an existing workflow instance.
///
@@ -37,7 +37,14 @@ public interface IWorkflowHost
public record StartWorkflowHostOptions(string? InstanceId = default, string? CorrelationId = default, IDictionary? Input = default, string? TriggerActivityId = default);
-public record ResumeWorkflowHostOptions(string? CorrelationId = default, string? BookmarkId = default, string? ActivityId = default, IDictionary? Input = default);
+public record ResumeWorkflowHostOptions(
+ string? CorrelationId = default,
+ string? BookmarkId = default,
+ string? ActivityId = default,
+ string? ActivityNodeId = default,
+ string? ActivityInstanceId = default,
+ string? ActivityHash = default,
+ IDictionary? Input = default);
public record StartWorkflowHostResult(Diff BookmarksDiff);
diff --git a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowRuntime.cs b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowRuntime.cs
index f7f48a8c0..a361766db 100644
--- a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowRuntime.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowRuntime.cs
@@ -92,7 +92,15 @@ public interface IWorkflowRuntime
public record StartWorkflowRuntimeOptions(string? CorrelationId = default, IDictionary? Input = default, VersionOptions VersionOptions = default, string? TriggerActivityId = default, string? InstanceId = default);
-public record ResumeWorkflowRuntimeOptions(string? CorrelationId = default, string? WorkflowInstanceId = default, string? BookmarkId = default, string? ActivityId = default, IDictionary? Input = default);
+public record ResumeWorkflowRuntimeOptions(
+ string? CorrelationId = default,
+ string? WorkflowInstanceId = default,
+ string? BookmarkId = default,
+ string? ActivityId = default,
+ string? ActivityNodeId = default,
+ string? ActivityInstanceId = default,
+ string? ActivityHash = default,
+ IDictionary? Input = default);
public record CanStartWorkflowResult(string? InstanceId, bool CanStart);
diff --git a/src/modules/Elsa.Workflows.Runtime/Handlers/DispatchWorkflowRequestHandler.cs b/src/modules/Elsa.Workflows.Runtime/Handlers/DispatchWorkflowRequestHandler.cs
index 1284b9be5..a6c499a6b 100644
--- a/src/modules/Elsa.Workflows.Runtime/Handlers/DispatchWorkflowRequestHandler.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Handlers/DispatchWorkflowRequestHandler.cs
@@ -38,7 +38,16 @@ internal class DispatchWorkflowRequestHandler :
public async Task HandleAsync(DispatchWorkflowInstanceCommand command, CancellationToken cancellationToken)
{
- var options = new ResumeWorkflowRuntimeOptions(command.CorrelationId, command.InstanceId, command.BookmarkId, command.ActivityId, command.Input);
+ var options = new ResumeWorkflowRuntimeOptions(
+ command.CorrelationId,
+ command.InstanceId,
+ command.BookmarkId,
+ command.ActivityId,
+ command.ActivityNodeId,
+ command.ActivityInstanceId,
+ command.ActivityHash,
+ command.Input);
+
await _workflowRuntime.ResumeWorkflowAsync(command.InstanceId, options, cancellationToken);
return Unit.Instance;
diff --git a/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowInstanceRequest.cs b/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowInstanceRequest.cs
index 15c8ecdc6..113df5752 100644
--- a/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowInstanceRequest.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowInstanceRequest.cs
@@ -4,5 +4,8 @@ public record DispatchWorkflowInstanceRequest(
string InstanceId,
string? BookmarkId = default,
string? ActivityId = default,
+ string? ActivityNodeId = default,
+ string? ActivityInstanceId = default,
+ string? ActivityHash = default,
IDictionary? Input = default,
string? CorrelationId = default);
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowRuntime.cs b/src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowRuntime.cs
index 90ae9f720..b3c98b981 100644
--- a/src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowRuntime.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowRuntime.cs
@@ -129,7 +129,15 @@ public class DefaultWorkflowRuntime : IWorkflowRuntime
var workflow = await _workflowDefinitionService.MaterializeWorkflowAsync(workflowDefinition, cancellationToken);
var workflowHost = await _workflowHostFactory.CreateAsync(workflow, workflowState, cancellationToken);
- var resumeWorkflowOptions = new ResumeWorkflowHostOptions(options.CorrelationId, options.BookmarkId, options.ActivityId, options.Input);
+
+ var resumeWorkflowOptions = new ResumeWorkflowHostOptions(
+ options.CorrelationId,
+ options.BookmarkId,
+ options.ActivityId,
+ options.ActivityNodeId,
+ options.ActivityInstanceId,
+ options.ActivityHash,
+ options.Input);
await workflowHost.ResumeWorkflowAsync(resumeWorkflowOptions, cancellationToken);
@@ -296,7 +304,7 @@ public class DefaultWorkflowRuntime : IWorkflowRuntime
var hash = _hasher.Hash(workflowsFilter.ActivityTypeName, workflowsFilter.BookmarkPayload);
var correlationId = workflowsFilter.Options.CorrelationId;
var workflowInstanceId = workflowsFilter.Options.WorkflowInstanceId;
- var filter = new BookmarkFilter { Hash = hash, CorrelationId = correlationId, WorkflowInstanceId = workflowInstanceId};
+ var filter = new BookmarkFilter { Hash = hash, CorrelationId = correlationId, WorkflowInstanceId = workflowInstanceId };
var bookmarks = await _bookmarkStore.FindManyAsync(filter, cancellationToken);
var collectedWorkflows = bookmarks.Select(b => new ResumableWorkflowMatch(b.WorkflowInstanceId, default, correlationId, b.BookmarkId)).ToList();
return collectedWorkflows;
diff --git a/src/modules/Elsa.Workflows.Runtime/Services/TaskBasedWorkflowDispatcher.cs b/src/modules/Elsa.Workflows.Runtime/Services/TaskBasedWorkflowDispatcher.cs
index 49a7a70a0..7cd57b9bd 100644
--- a/src/modules/Elsa.Workflows.Runtime/Services/TaskBasedWorkflowDispatcher.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Services/TaskBasedWorkflowDispatcher.cs
@@ -37,7 +37,16 @@ public class TaskBasedWorkflowDispatcher : IWorkflowDispatcher
///
public async Task DispatchAsync(DispatchWorkflowInstanceRequest request, CancellationToken cancellationToken = default)
{
- var command = new DispatchWorkflowInstanceCommand(request.InstanceId, request.BookmarkId, request.ActivityId, request.Input, request.CorrelationId);
+ var command = new DispatchWorkflowInstanceCommand(
+ request.InstanceId,
+ request.BookmarkId,
+ request.ActivityId,
+ request.ActivityNodeId,
+ request.ActivityInstanceId,
+ request.ActivityHash,
+ request.Input,
+ request.CorrelationId);
+
await _backgroundCommandSender.SendAsync(command, cancellationToken);
return new DispatchWorkflowInstanceResponse();
}
diff --git a/src/modules/Elsa.Workflows.Runtime/Services/WorkflowHost.cs b/src/modules/Elsa.Workflows.Runtime/Services/WorkflowHost.cs
index 163ac414c..2f9fd6f51 100644
--- a/src/modules/Elsa.Workflows.Runtime/Services/WorkflowHost.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Services/WorkflowHost.cs
@@ -38,7 +38,7 @@ public class WorkflowHost : IWorkflowHost
///
public Workflow Workflow { get; set; }
-
+
///
public WorkflowState WorkflowState { get; set; }
@@ -84,7 +84,7 @@ public class WorkflowHost : IWorkflowHost
public async Task ResumeWorkflowAsync(ResumeWorkflowHostOptions? options = default, CancellationToken cancellationToken = default)
{
var originalBookmarks = WorkflowState.Bookmarks.ToList();
-
+
if (WorkflowState.Status != WorkflowStatus.Running)
{
_logger.LogWarning("Attempt to resume workflow {WorkflowInstanceId} that is not in the Running state. The actual state is {ActualWorkflowStatus}", WorkflowState.Id, WorkflowState.Status);
@@ -93,11 +93,22 @@ public class WorkflowHost : IWorkflowHost
var instanceId = WorkflowState.Id;
var input = options?.Input;
- var runOptions = new RunWorkflowOptions(instanceId, options?.CorrelationId, options?.BookmarkId, options?.ActivityId, input);
+
+ var runOptions = new RunWorkflowOptions(
+ instanceId,
+ options?.CorrelationId,
+ options?.BookmarkId,
+ options?.ActivityId,
+ options?.ActivityNodeId,
+ options?.ActivityInstanceId,
+ options?.ActivityHash,
+ input
+ );
+
var workflowResult = await _workflowRunner.RunAsync(Workflow, WorkflowState, runOptions, cancellationToken);
WorkflowState = workflowResult.WorkflowState;
-
+
var updatedBookmarks = WorkflowState.Bookmarks;
return new ResumeWorkflowHostResult(Diff.For(originalBookmarks, updatedBookmarks));
}