Update Flowchart completion logic

In addition to taking into account scheduled work, also check if there are actual activity instances still running
This commit is contained in:
Sipke Schoorstra 2023-08-04 11:45:07 +02:00
parent 226c25169f
commit 815b544f53
13 changed files with 1596 additions and 21 deletions

View file

@ -144,19 +144,13 @@ public class Flowchart : Container
/// </summary>
private bool HasPendingWork(WorkflowExecutionContext workflowExecutionContext)
{
var scheduler = workflowExecutionContext.Scheduler;
var workItems = scheduler.List();
var activityNodeIds = workItems.Select(x => x.ActivityId).ToList();
var flowchartChildNodeIds = Activities.Select(workflowExecutionContext.FindNodeByActivity).Select(x => x.NodeId).ToList();
var hasPendingWork = activityNodeIds.Intersect(flowchartChildNodeIds).Any();
return hasPendingWork;
}
private bool HaveAllLeafsExecuted(FlowScope scope)
{
var leafs = Activities.Where(x => Connections.All(y => y.Source != x)).ToList();
var leafsExecuted = leafs.All(x => scope.GetExecutionCount(x) > 0);
return leafsExecuted;
var activityIds = Activities.Select(x => x.Id).ToList();
var activityNodeIds = workflowExecutionContext.Workflow.ToolVersion.Major >= 3 ? activityIds : workflowExecutionContext.Nodes.Where(x => activityIds.Contains(x.Activity.Id)).Select(x => x.NodeId).ToList();
var activityExecutionContexts = workflowExecutionContext.ActivityExecutionContexts.Where(x => activityIds.Contains(x.Activity.Id)).ToList();
var hasPendingWork = workflowExecutionContext.Scheduler.List().Any(x => activityNodeIds.Contains(x.ActivityId));
var hasRunningActivityInstances = activityExecutionContexts.Any(x => x.Status == ActivityStatus.Running);
return hasRunningActivityInstances || hasPendingWork;
}
private IActivity? GetStartActivity(ActivityExecutionContext context)

View file

@ -102,7 +102,9 @@ public static class WorkflowExecutionContextExtensions
object? tag = default)
{
var activityInvoker = workflowExecutionContext.GetRequiredService<IActivityInvoker>();
var workItem = new ActivityWorkItem(activityNode.NodeId, async () => await activityInvoker.InvokeAsync(workflowExecutionContext, activityNode.Activity, owner), tag);
var toolVersion = workflowExecutionContext.Workflow.ToolVersion;
var activityId = toolVersion.Major >= 3 ? activityNode.Activity.Id : activityNode.NodeId;
var workItem = new ActivityWorkItem(activityId, async () => await activityInvoker.InvokeAsync(workflowExecutionContext, activityNode.Activity, owner), tag);
workflowExecutionContext.Scheduler.Schedule(workItem);
workflowExecutionContext.AddCompletionCallback(owner, activityNode, completionCallback);
}

View file

@ -58,16 +58,16 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Scenarios\FlowchartCompletion\Workflows\workflow1.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Scenarios\FlowchartCompletion\Workflows\workflow2.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Scenarios\FlowchartCompletion\Workflows\workflow3.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Scenarios\FlowchartCompletion\Workflows\workflow4.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Scenarios\ImportAndExecute\Workflows\implicit-loop.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@ -84,6 +84,9 @@
<None Update="Scenarios\DependencyWorkflows\Workflows\molecule-activity.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Scenarios\FlowchartCompletion\Workflows\workflow5.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View file

@ -25,6 +25,7 @@ public class Tests
[InlineData("workflow2.json")]
[InlineData("workflow3.json")]
[InlineData("workflow4.json")]
[InlineData("workflow5.json")]
public async Task Test1(string workflowFileName)
{
// Populate registries.

View file

@ -1 +1,127 @@
{"id":"f7f7563b32de444797363df61e5109d3","definitionId":"d91eff09eaad43efb9d58332f1f22c82","name":"Flows","createdAt":"2023-04-18T13:32:26.294066+00:00","version":5,"variables":[],"inputs":[],"outputs":[],"outcomes":[],"metadata":{},"isLatest":true,"isPublished":false,"root":{"type":"Elsa.Flowchart","version":1,"id":"Flowchart1","metadata":{},"applicationProperties":{"NotFoundConnectionsKey":[]},"start":"WriteLine1","activities":[{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine1"},"memoryReference":{"id":"WriteLine1:input-1"}},"id":"WriteLine1","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2020,"y":2320}},"displayText":"WriteLine1"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine2"},"memoryReference":{"id":"WriteLine2:input-1"}},"id":"WriteLine2","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2260,"y":2260}},"displayText":"WriteLine2"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine3"},"memoryReference":{"id":"WriteLine3:input-1"}},"id":"WriteLine3","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2260,"y":2380}},"displayText":"WriteLine3"}}],"connections":[{"source":"WriteLine1","target":"WriteLine2","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine1","target":"WriteLine3","sourcePort":"Done","targetPort":"In"}]}}
{
"id": "f7f7563b32de444797363df61e5109d3",
"definitionId": "d91eff09eaad43efb9d58332f1f22c82",
"name": "Flows",
"createdAt": "2023-04-18T13:32:26.294066+00:00",
"version": 1,
"variables": [],
"inputs": [],
"outputs": [],
"outcomes": [],
"metadata": {},
"isLatest": true,
"isPublished": false,
"root": {
"type": "Elsa.Flowchart",
"version": 1,
"id": "Flowchart1",
"metadata": {},
"applicationProperties": {
"NotFoundConnectionsKey": []
},
"start": "WriteLine1",
"activities": [
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine1"
},
"memoryReference": {
"id": "WriteLine1:input-1"
}
},
"id": "WriteLine1",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2020,
"y": 2320
}
},
"displayText": "WriteLine1"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine2"
},
"memoryReference": {
"id": "WriteLine2:input-1"
}
},
"id": "WriteLine2",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2260,
"y": 2260
}
},
"displayText": "WriteLine2"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine3"
},
"memoryReference": {
"id": "WriteLine3:input-1"
}
},
"id": "WriteLine3",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2260,
"y": 2380
}
},
"displayText": "WriteLine3"
}
}
],
"connections": [
{
"source": "WriteLine1",
"target": "WriteLine2",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine1",
"target": "WriteLine3",
"sourcePort": "Done",
"targetPort": "In"
}
]
}
}

View file

@ -1 +1,361 @@
{"id":"dc6576d848aa4f46812356467575705f","definitionId":"991a4f39f7074a9988465230cfdb8d81","name":"Braided flow","createdAt":"2023-04-18T13:45:03.454228+00:00","version":4,"variables":[],"inputs":[],"outputs":[],"outcomes":[],"metadata":{},"isLatest":true,"isPublished":false,"root":{"type":"Elsa.Flowchart","version":1,"id":"Flowchart1","metadata":{},"applicationProperties":{"NotFoundConnectionsKey":[]},"start":"WriteLine1","activities":[{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine7"},"memoryReference":{"id":"WriteLine7:input-1"}},"id":"WriteLine7","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2340,"y":2220}},"displayText":"WriteLine7"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine9"},"memoryReference":{"id":"WriteLine9:input-1"}},"id":"WriteLine9","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2560,"y":2320}},"displayText":"WriteLine9"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine1"},"memoryReference":{"id":"WriteLine1:input-1"}},"id":"WriteLine1","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":1600,"y":2320}},"displayText":"WriteLine1"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine2"},"memoryReference":{"id":"WriteLine2:input-1"}},"id":"WriteLine2","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":1820,"y":2220}},"displayText":"WriteLine2"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine3"},"memoryReference":{"id":"WriteLine3:input-1"}},"id":"WriteLine3","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":1820,"y":2400}},"displayText":"WriteLine3"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine4"},"memoryReference":{"id":"WriteLine4:input-1"}},"id":"WriteLine4","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2060,"y":2160}},"displayText":"WriteLine4"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine5"},"memoryReference":{"id":"WriteLine5:input-1"}},"id":"WriteLine5","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2060,"y":2320}},"displayText":"WriteLine5"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine6"},"memoryReference":{"id":"WriteLine6:input-1"}},"id":"WriteLine6","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2060,"y":2480}},"displayText":"WriteLine6"}},{"text":{"typeName":"String","expression":{"type":"Literal","value":"WriteLine8"},"memoryReference":{"id":"WriteLine8:input-1"}},"id":"WriteLine8","type":"Elsa.WriteLine","version":1,"canStartWorkflow":false,"runAsynchronously":false,"customProperties":{},"source":null,"line":null,"metadata":{"designer":{"position":{"x":2340,"y":2400}},"displayText":"WriteLine8"}}],"connections":[{"source":"WriteLine5","target":"WriteLine7","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine8","target":"WriteLine9","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine7","target":"WriteLine9","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine1","target":"WriteLine2","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine2","target":"WriteLine4","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine3","target":"WriteLine5","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine1","target":"WriteLine3","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine4","target":"WriteLine7","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine2","target":"WriteLine5","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine6","target":"WriteLine8","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine3","target":"WriteLine6","sourcePort":"Done","targetPort":"In"},{"source":"WriteLine5","target":"WriteLine8","sourcePort":"Done","targetPort":"In"}]}}
{
"id": "dc6576d848aa4f46812356467575705f",
"definitionId": "991a4f39f7074a9988465230cfdb8d81",
"name": "Braided flow",
"createdAt": "2023-04-18T13:45:03.454228+00:00",
"version": 1,
"variables": [],
"inputs": [],
"outputs": [],
"outcomes": [],
"metadata": {},
"isLatest": true,
"isPublished": false,
"root": {
"type": "Elsa.Flowchart",
"version": 1,
"id": "Flowchart1",
"metadata": {},
"applicationProperties": {
"NotFoundConnectionsKey": []
},
"start": "WriteLine1",
"activities": [
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine7"
},
"memoryReference": {
"id": "WriteLine7:input-1"
}
},
"id": "WriteLine7",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2340,
"y": 2220
}
},
"displayText": "WriteLine7"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine9"
},
"memoryReference": {
"id": "WriteLine9:input-1"
}
},
"id": "WriteLine9",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2560,
"y": 2320
}
},
"displayText": "WriteLine9"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine1"
},
"memoryReference": {
"id": "WriteLine1:input-1"
}
},
"id": "WriteLine1",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 1600,
"y": 2320
}
},
"displayText": "WriteLine1"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine2"
},
"memoryReference": {
"id": "WriteLine2:input-1"
}
},
"id": "WriteLine2",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 1820,
"y": 2220
}
},
"displayText": "WriteLine2"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine3"
},
"memoryReference": {
"id": "WriteLine3:input-1"
}
},
"id": "WriteLine3",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 1820,
"y": 2400
}
},
"displayText": "WriteLine3"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine4"
},
"memoryReference": {
"id": "WriteLine4:input-1"
}
},
"id": "WriteLine4",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2060,
"y": 2160
}
},
"displayText": "WriteLine4"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine5"
},
"memoryReference": {
"id": "WriteLine5:input-1"
}
},
"id": "WriteLine5",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2060,
"y": 2320
}
},
"displayText": "WriteLine5"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine6"
},
"memoryReference": {
"id": "WriteLine6:input-1"
}
},
"id": "WriteLine6",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2060,
"y": 2480
}
},
"displayText": "WriteLine6"
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "WriteLine8"
},
"memoryReference": {
"id": "WriteLine8:input-1"
}
},
"id": "WriteLine8",
"type": "Elsa.WriteLine",
"version": 1,
"canStartWorkflow": false,
"runAsynchronously": false,
"customProperties": {},
"source": null,
"line": null,
"metadata": {
"designer": {
"position": {
"x": 2340,
"y": 2400
}
},
"displayText": "WriteLine8"
}
}
],
"connections": [
{
"source": "WriteLine5",
"target": "WriteLine7",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine8",
"target": "WriteLine9",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine7",
"target": "WriteLine9",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine1",
"target": "WriteLine2",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine2",
"target": "WriteLine4",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine3",
"target": "WriteLine5",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine1",
"target": "WriteLine3",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine4",
"target": "WriteLine7",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine2",
"target": "WriteLine5",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine6",
"target": "WriteLine8",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine3",
"target": "WriteLine6",
"sourcePort": "Done",
"targetPort": "In"
},
{
"source": "WriteLine5",
"target": "WriteLine8",
"sourcePort": "Done",
"targetPort": "In"
}
]
}
}

View file

@ -0,0 +1,207 @@
{
"id": "3365d4c0198e459f834b799cbfe91154",
"definitionId": "4aa1e566da264ab6b5495bedb734096d",
"name": "Forking, Containment and Blocking",
"description": "A combination of a fork, a containment and a blocking activity.",
"version": 1,
"toolVersion": "3.0.0.0",
"variables": [],
"inputs": [],
"outputs": [],
"outcomes": [],
"customProperties": {},
"isReadonly": false,
"isLatest": true,
"isPublished": true,
"root": {
"type": "Elsa.Flowchart",
"version": 1,
"id": "uEnFWEdaWkadgIMHT2umLA",
"metadata": {},
"customProperties": {
"NotFoundConnectionsKey": [],
"canStartWorkflow": false,
"runAsynchronously": false
},
"activities": [
{
"id": "MLDV_altcUO5MwP7p5xJWw",
"name": "Start1",
"type": "Elsa.Start",
"version": 1,
"customProperties": {
"canStartWorkflow": false,
"runAsynchronously": false
},
"metadata": {
"designer": {
"position": {
"x": -480,
"y": -566.046875
},
"size": {
"width": 102.21875,
"height": 50
}
}
}
},
{
"text": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "Intermediary"
},
"memoryReference": {
"id": "EIh3Q0Um1U-QSCh1b3GBjQ:input-0"
}
},
"id": "EIh3Q0Um1U-QSCh1b3GBjQ",
"name": "WriteLine1",
"type": "Elsa.WriteLine",
"version": 1,
"customProperties": {
"canStartWorkflow": false,
"runAsynchronously": false
},
"metadata": {
"designer": {
"position": {
"x": -228.5,
"y": -476.046875
},
"size": {
"width": 139.296875,
"height": 50
}
}
}
},
{
"text": null,
"id": "0Z7Velr5CEW_r7YYoeEjBQ",
"name": "WriteLine2",
"type": "Elsa.WriteLine",
"version": 1,
"customProperties": {
"canStartWorkflow": false,
"runAsynchronously": false
},
"metadata": {
"designer": {
"position": {
"x": 69.34375,
"y": -476.046875
},
"size": {
"width": 139.296875,
"height": 50
}
}
}
},
{
"body": {
"type": "Elsa.Flowchart",
"version": 1,
"id": "NJ5fh2bUWU-TxWeXsbNaSg",
"metadata": {},
"customProperties": {
"NotFoundConnectionsKey": [],
"canStartWorkflow": false,
"runAsynchronously": false
},
"activities": [
{
"eventName": {
"typeName": "String",
"expression": {
"type": "Literal",
"value": "Event4"
},
"memoryReference": {
"id": "8KVHRw-WpUizyxOq0C6Nvg:input-0"
}
},
"result": null,
"id": "8KVHRw-WpUizyxOq0C6Nvg",
"name": "Event1",
"type": "Elsa.Event",
"version": 1,
"customProperties": {
"canStartWorkflow": false,
"runAsynchronously": false
},
"metadata": {
"designer": {
"position": {
"x": -840,
"y": -500
},
"size": {
"width": 106.828125,
"height": 50
}
}
}
}
],
"connections": []
},
"id": "HG4wfBhvlEW_149HwNyzHw",
"name": "FlowNode1",
"type": "Elsa.FlowNode",
"version": 1,
"customProperties": {
"canStartWorkflow": false,
"runAsynchronously": false
},
"metadata": {
"designer": {
"position": {
"x": -228.5,
"y": -704.109375
},
"size": {
"width": 211.15625,
"height": 120
}
}
}
}
],
"connections": [
{
"source": {
"activity": "MLDV_altcUO5MwP7p5xJWw",
"port": "Done"
},
"target": {
"activity": "HG4wfBhvlEW_149HwNyzHw",
"port": "In"
}
},
{
"source": {
"activity": "MLDV_altcUO5MwP7p5xJWw",
"port": "Done"
},
"target": {
"activity": "EIh3Q0Um1U-QSCh1b3GBjQ",
"port": "In"
}
},
{
"source": {
"activity": "EIh3Q0Um1U-QSCh1b3GBjQ",
"port": "Done"
},
"target": {
"activity": "0Z7Velr5CEW_r7YYoeEjBQ",
"port": "In"
}
}
]
}
}