Skip to content

Commit 3bd961c

Browse files
davidmrdavidGreg Roll
andauthored
Return results from Start-DurableExternalEventListener (#685) (#753)
Co-authored-by: Greg Roll <[email protected]>
1 parent e189677 commit 3bd961c

File tree

9 files changed

+79
-15
lines changed

9 files changed

+79
-15
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member 'member'
7+
8+
namespace Microsoft.Azure.Functions.PowerShellWorker.Durable.Commands
9+
{
10+
using System.Collections;
11+
using System.Management.Automation;
12+
using Microsoft.Azure.Functions.PowerShellWorker.Durable.Tasks;
13+
14+
[Cmdlet("Get", "DurableTaskResult")]
15+
public class GetDurableTaskResultCommand : PSCmdlet
16+
{
17+
[Parameter(Mandatory = true)]
18+
[ValidateNotNull]
19+
public DurableTask[] Task { get; set; }
20+
21+
private readonly DurableTaskHandler _durableTaskHandler = new DurableTaskHandler();
22+
23+
protected override void EndProcessing()
24+
{
25+
var privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData;
26+
var context = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey];
27+
28+
_durableTaskHandler.GetTaskResult(Task, context, WriteObject);
29+
}
30+
31+
protected override void StopProcessing()
32+
{
33+
_durableTaskHandler.Stop();
34+
}
35+
}
36+
}

src/Durable/DurableTaskHandler.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ public void WaitAny(
164164
if (scheduledHistoryEvent != null)
165165
{
166166
scheduledHistoryEvent.IsProcessed = true;
167+
scheduledHistoryEvent.IsPlayed = true;
167168
}
168169

169170
if (completedHistoryEvent != null)
@@ -179,6 +180,7 @@ public void WaitAny(
179180
}
180181

181182
completedHistoryEvent.IsProcessed = true;
183+
completedHistoryEvent.IsPlayed = true;
182184
}
183185
}
184186

@@ -195,6 +197,21 @@ public void WaitAny(
195197
}
196198
}
197199

200+
public void GetTaskResult(
201+
IReadOnlyCollection<DurableTask> tasksToQueryResultFor,
202+
OrchestrationContext context,
203+
Action<object> output)
204+
{
205+
foreach (var task in tasksToQueryResultFor) {
206+
var scheduledHistoryEvent = task.GetScheduledHistoryEvent(context, true);
207+
var processedHistoryEvent = task.GetCompletedHistoryEvent(context, scheduledHistoryEvent, true);
208+
if (processedHistoryEvent != null)
209+
{
210+
output(GetEventResult(processedHistoryEvent));
211+
}
212+
}
213+
}
214+
198215
public void Stop()
199216
{
200217
_waitForStop.Set();

src/Durable/Tasks/ActivityInvocationTask.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ internal ActivityInvocationTask(string functionName, object functionInput)
3737
{
3838
}
3939

40-
internal override HistoryEvent GetScheduledHistoryEvent(OrchestrationContext context)
40+
internal override HistoryEvent GetScheduledHistoryEvent(OrchestrationContext context, bool processed)
4141
{
4242
return context.History.FirstOrDefault(
4343
e => e.EventType == HistoryEventType.TaskScheduled &&
4444
e.Name == FunctionName &&
45-
!e.IsProcessed);
45+
e.IsProcessed == processed);
4646
}
4747

48-
internal override HistoryEvent GetCompletedHistoryEvent(OrchestrationContext context, HistoryEvent scheduledHistoryEvent)
48+
internal override HistoryEvent GetCompletedHistoryEvent(OrchestrationContext context, HistoryEvent scheduledHistoryEvent, bool processed)
4949
{
5050
return scheduledHistoryEvent == null
5151
? null

src/Durable/Tasks/DurableTask.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ namespace Microsoft.Azure.Functions.PowerShellWorker.Durable.Tasks
1111

1212
public abstract class DurableTask
1313
{
14-
internal abstract HistoryEvent GetScheduledHistoryEvent(OrchestrationContext context);
14+
internal abstract HistoryEvent GetScheduledHistoryEvent(OrchestrationContext context, bool processed = false);
1515

16-
internal abstract HistoryEvent GetCompletedHistoryEvent(OrchestrationContext context, HistoryEvent scheduledHistoryEvent);
16+
internal abstract HistoryEvent GetCompletedHistoryEvent(OrchestrationContext context, HistoryEvent scheduledHistoryEvent, bool processed = false);
1717

1818
internal abstract OrchestrationAction CreateOrchestrationAction();
1919
}

src/Durable/Tasks/DurableTimerTask.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ internal DurableTimerTask(
2828
Action = new CreateDurableTimerAction(FireAt);
2929
}
3030

31-
internal override HistoryEvent GetScheduledHistoryEvent(OrchestrationContext context)
31+
internal override HistoryEvent GetScheduledHistoryEvent(OrchestrationContext context, bool processed)
3232
{
3333
return context.History.FirstOrDefault(
3434
e => e.EventType == HistoryEventType.TimerCreated &&
3535
e.FireAt.Equals(FireAt) &&
3636
!e.IsProcessed);
3737
}
3838

39-
internal override HistoryEvent GetCompletedHistoryEvent(OrchestrationContext context, HistoryEvent scheduledHistoryEvent)
39+
internal override HistoryEvent GetCompletedHistoryEvent(OrchestrationContext context, HistoryEvent scheduledHistoryEvent, bool processed)
4040
{
4141
return scheduledHistoryEvent == null
4242
? null

src/Durable/Tasks/ExternalEventTask.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ public ExternalEventTask(string externalEventName)
2121
}
2222

2323
// There is no corresponding history event for an expected external event
24-
internal override HistoryEvent GetScheduledHistoryEvent(OrchestrationContext context)
24+
internal override HistoryEvent GetScheduledHistoryEvent(OrchestrationContext context, bool processed)
2525
{
2626
return null;
2727
}
2828

29-
internal override HistoryEvent GetCompletedHistoryEvent(OrchestrationContext context, HistoryEvent taskScheduled)
29+
internal override HistoryEvent GetCompletedHistoryEvent(OrchestrationContext context, HistoryEvent taskScheduled, bool processed)
3030
{
3131
return context.History.FirstOrDefault(
3232
e => e.EventType == HistoryEventType.EventRaised &&
3333
e.Name == ExternalEventName &&
34-
!e.IsProcessed);
34+
e.IsPlayed == processed);
3535
}
3636

3737
internal override OrchestrationAction CreateOrchestrationAction()

src/Modules/Microsoft.Azure.Functions.PowerShellWorker/Microsoft.Azure.Functions.PowerShellWorker.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ FunctionsToExport = @(
5959
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
6060
CmdletsToExport = @(
6161
'Get-OutputBinding',
62+
'Get-DurableTaskResult'
6263
'Invoke-DurableActivity',
6364
'Push-OutputBinding',
6465
'Set-DurableCustomStatus',

src/Modules/Microsoft.Azure.Functions.PowerShellWorker/Microsoft.Azure.Functions.PowerShellWorker.psm1

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ function New-DurableOrchestrationCheckStatusResponse {
235235
The TaskHubName of the orchestration instance that will handle the external event.
236236
.PARAMETER ConnectionName
237237
The name of the connection string associated with TaskHubName
238+
.PARAMETER AppCode
239+
The Azure Functions system key
238240
#>
239241
function Send-DurableExternalEvent {
240242
[CmdletBinding()]
@@ -263,12 +265,16 @@ function Send-DurableExternalEvent {
263265

264266
[Parameter(
265267
ValueFromPipelineByPropertyName=$true)]
266-
[string] $ConnectionName
268+
[string] $ConnectionName,
269+
270+
[Parameter(
271+
ValueFromPipelineByPropertyName=$true)]
272+
[string] $AppCode
267273
)
268274

269275
$DurableClient = GetDurableClientFromModulePrivateData
270276

271-
$RequestUrl = GetRaiseEventUrl -DurableClient $DurableClient -InstanceId $InstanceId -EventName $EventName -TaskHubName $TaskHubName -ConnectionName $ConnectionName
277+
$RequestUrl = GetRaiseEventUrl -DurableClient $DurableClient -InstanceId $InstanceId -EventName $EventName -TaskHubName $TaskHubName -ConnectionName $ConnectionName -AppCode $AppCode
272278

273279
$Body = $EventData | ConvertTo-Json -Compress
274280

@@ -280,7 +286,8 @@ function GetRaiseEventUrl(
280286
[string] $InstanceId,
281287
[string] $EventName,
282288
[string] $TaskHubName,
283-
[string] $ConnectionName) {
289+
[string] $ConnectionName,
290+
[string] $AppCode) {
284291

285292
$RequestUrl = $DurableClient.BaseUrl + "/instances/$InstanceId/raiseEvent/$EventName"
286293

@@ -291,6 +298,9 @@ function GetRaiseEventUrl(
291298
if ($null -eq $ConnectionName) {
292299
$query += "connection=$ConnectionName"
293300
}
301+
if ($null -eq $AppCode) {
302+
$query += "code=$AppCode"
303+
}
294304
if ($query.Count -gt 0) {
295305
$RequestUrl += "?" + [string]::Join("&", $query)
296306
}

test/Unit/Durable/ActivityInvocationTaskTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ public void GetCompletedHistoryEvent_ReturnsTaskCompletedOrTaskFailed(bool succe
225225
var orchestrationContext = new OrchestrationContext { History = history };
226226

227227
var task = new ActivityInvocationTask(FunctionName, FunctionInput);
228-
var scheduledEvent = task.GetScheduledHistoryEvent(orchestrationContext);
229-
var completedEvent = task.GetCompletedHistoryEvent(orchestrationContext, scheduledEvent);
228+
var scheduledEvent = task.GetScheduledHistoryEvent(orchestrationContext, false);
229+
var completedEvent = task.GetCompletedHistoryEvent(orchestrationContext, scheduledEvent, false);
230230

231231
Assert.Equal(scheduledEvent.EventId, completedEvent.TaskScheduledId);
232232
}

0 commit comments

Comments
 (0)