Skip to content

Commit 0ed0a0e

Browse files
authored
Add RetryOptions alias, add Get-DurableTaskResult + E2E test (#45)
1 parent 8db714c commit 0ed0a0e

File tree

19 files changed

+96
-50
lines changed

19 files changed

+96
-50
lines changed

src/AzureFunctions.PowerShell.Durable.SDK.psd1

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,14 @@
7373
CmdletsToExport = @(
7474
'Invoke-DurableActivity',
7575
'Invoke-DurableSubOrchestrator',
76-
'New-DurableRetryOptionsE',
76+
'New-DurableRetryPolicy',
7777
'Set-DurableCustomStatus',
7878
'Set-FunctionInvocationContext',
7979
'Start-DurableExternalEventListener'
8080
'Start-DurableTimer',
8181
'Stop-DurableTimerTask',
82-
'Wait-DurableTask'
82+
'Wait-DurableTask',
83+
'Get-DurableTaskResult'
8384
)
8485

8586
# Variables to export from this module
@@ -90,7 +91,8 @@
9091
'Invoke-ActivityFunction',
9192
'New-OrchestrationCheckStatusResponse',
9293
'Start-NewOrchestration',
93-
'Wait-ActivityFunction'
94+
'Wait-ActivityFunction',
95+
'New-DurableRetryOptions'
9496
)
9597

9698
# DSC resources to export from this module

src/AzureFunctions.PowerShell.Durable.SDK.psm1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ Set-Alias -Name Wait-ActivityFunction -Value Wait-DurableTask
1010
Set-Alias -Name Invoke-ActivityFunction -Value Invoke-DurableActivity
1111
Set-Alias -Name New-OrchestrationCheckStatusResponse -Value New-DurableOrchestrationCheckStatusResponse
1212
Set-Alias -Name Start-NewOrchestration -Value Start-DurableOrchestration
13+
Set-Alias -Name New-DurableRetryOptions -Value New-DurableRetryPolicy
1314

1415
function GetDurableClientFromModulePrivateData {
1516
$PrivateData = $PSCmdlet.MyInvocation.MyCommand.Module.PrivateData
1617
if ($null -eq $PrivateData -or $null -eq $PrivateData['DurableClient']) {
17-
throw "No binding of the type 'durableClient' was defined."
18+
throw "Could not find `DurableClient` private data. This can occur when you have not set application setting 'ExternalDurablePowerShellSDK' to 'true' or if you're using a DurableClient CmdLet but have no DurableClient binding declared in `function.json`."
1819
}
1920
else {
2021
$PrivateData['DurableClient']

src/DurableEngine/Actions/CallActivityWithRetryAction.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ internal class CallActivityWithRetryAction : OrchestrationAction
2828
/// </summary>
2929
public readonly Dictionary<string, object> RetryOptions;
3030

31-
internal CallActivityWithRetryAction(string functionName, object input, RetryOptions retryOptions)
31+
internal CallActivityWithRetryAction(string functionName, object input, RetryPolicy retryOptions)
3232
: base(ActionType.CallActivityWithRetry)
3333
{
3434
FunctionName = functionName;
3535
Input = input;
36-
RetryOptions = retryOptions.RetryOptionsDictionary;
36+
RetryOptions = retryOptions.RetryPolicyDictionary;
3737
}
3838
}
3939
}

src/DurableEngine/Actions/CallSubOrchestratorWithRetryAction.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ internal class CallSubOrchestratorWithRetryAction : OrchestrationAction
2929
/// </summary>
3030
public readonly Dictionary<string, object> RetryOptions;
3131

32-
internal CallSubOrchestratorWithRetryAction(string functionName, object input, string instanceId, RetryOptions retryOptions)
32+
internal CallSubOrchestratorWithRetryAction(string functionName, object input, string instanceId, RetryPolicy retryOptions)
3333
: base(ActionType.CallSubOrchestratorWithRetry)
3434
{
3535
FunctionName = functionName;
3636
InstanceId = instanceId;
3737
Input = input;
38-
RetryOptions = retryOptions.RetryOptionsDictionary;
38+
RetryOptions = retryOptions.RetryPolicyDictionary;
3939
}
4040
}
4141
}

src/DurableEngine/RetryOptions.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ namespace DurableEngine
1414
/// <summary>
1515
/// Defines retry policies that can be passed as parameters to various operations.
1616
/// </summary>
17-
public class RetryOptions : RetryPolicy
17+
public class RetryPolicy : Microsoft.DurableTask.RetryPolicy
1818
{
19-
internal Dictionary<string, object> RetryOptionsDictionary { get; set; }
19+
internal Dictionary<string, object> RetryPolicyDictionary { get; set; }
2020

2121
/// <inheritdoc/>
22-
public RetryOptions(
22+
public RetryPolicy(
2323
int maxNumberOfAttempts,
2424
TimeSpan firstRetryInterval,
2525
double backoffCoefficient,
@@ -40,14 +40,14 @@ public RetryOptions(
4040
// defaults for the optional MaxRetryInterval and RetryTimeOut parameters. Furthermore,
4141
// of RetryOptions cannot be modified after construction, so it is safe to do this eager
4242
// serialization in the constructor.
43-
RetryOptionsDictionary = new Dictionary<string, object>()
43+
RetryPolicyDictionary = new Dictionary<string, object>()
4444
{
4545
{ "firstRetryIntervalInMilliseconds", ToIntMilliseconds(firstRetryInterval) },
4646
{ "maxNumberOfAttempts", maxNumberOfAttempts },
4747
{ "backoffCoefficient", backoffCoefficient }
4848
};
49-
AddOptionalValue(RetryOptionsDictionary, "maxRetryIntervalInMilliseconds", maxRetryInterval, ToIntMilliseconds);
50-
AddOptionalValue(RetryOptionsDictionary, "maxRetryIntervalInMilliseconds", retryTimeout, ToIntMilliseconds);
49+
AddOptionalValue(RetryPolicyDictionary, "maxRetryIntervalInMilliseconds", maxRetryInterval, ToIntMilliseconds);
50+
AddOptionalValue(RetryPolicyDictionary, "maxRetryIntervalInMilliseconds", retryTimeout, ToIntMilliseconds);
5151
}
5252

5353
private static void AddOptionalValue<T>(

src/DurableEngine/Tasks/ActivityInvocationTask.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ public class ActivityInvocationTask : DurableTask
2222

2323
internal object Input { get; }
2424

25-
private RetryOptions RetryOptions { get; }
25+
private DurableEngine.RetryPolicy RetryOptions { get; }
2626

2727
public ActivityInvocationTask(
2828
string functionName,
2929
object functionInput,
30-
RetryOptions retryOptions,
30+
DurableEngine.RetryPolicy retryOptions,
3131
SwitchParameter noWait,
3232
Hashtable privateData) : base(noWait, privateData)
3333
{

src/DurableEngine/Tasks/DurableTask.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections;
44
using System.Management.Automation;
55
using System.Threading.Tasks;
6+
using static System.Collections.Specialized.BitVector32;
67

78
namespace DurableEngine.Tasks
89
{
@@ -17,6 +18,17 @@ public DurableTask(SwitchParameter noWait, Hashtable privateData)
1718
OrchestrationContext = (OrchestrationContext)privateData[OrchestrationInvoker.ContextKey];
1819
}
1920

21+
private OrchestrationAction action;
22+
23+
internal OrchestrationAction GetOrCreateAction()
24+
{
25+
if (this.action == null)
26+
{
27+
this.action = this.CreateOrchestrationAction();
28+
}
29+
return this.action;
30+
}
31+
2032
/// <summary>
2133
/// The orchestrator context.
2234
/// </summary>
@@ -49,7 +61,13 @@ public void Execute(Action<object> write, Action<ErrorRecord> writeErr)
4961
{
5062
// Flag this task as the current "task-to-await"
5163
OrchestrationContext.SharedMemory.currTask = task;
52-
OrchestrationContext.SharedMemory.Add(task.CreateOrchestrationAction());
64+
65+
// DF APIs only generate an action once, otherwise we'll get duplicate executions
66+
if (task.action == null)
67+
{
68+
// generate and cache action
69+
OrchestrationContext.SharedMemory.Add(task.GetOrCreateAction());
70+
}
5371

5472
// Signal orchestration thread to await the Task.
5573
// This is necessary for DTFx to determine if a result exists for the Task.

src/DurableEngine/Tasks/SubOrchestratorTask.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ public class SubOrchestratorTask : DurableTask
1818

1919
internal object Input { get; }
2020

21-
private RetryOptions RetryOptions { get; }
21+
private RetryPolicy RetryOptions { get; }
2222

2323
public SubOrchestratorTask(
2424
string functionName,
2525
string instanceId,
2626
object functionInput,
27-
RetryOptions retryOptions,
27+
RetryPolicy retryOptions,
2828
SwitchParameter noWait,
2929
Hashtable privateData) : base(noWait, privateData)
3030
{

src/DurableEngine/Tasks/WhenAllTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ internal override Task CreateDTFxTask()
4343

4444
internal override OrchestrationAction CreateOrchestrationAction()
4545
{
46-
var compoundActions = Tasks.Select((task) => task.CreateOrchestrationAction()).ToArray();
46+
var compoundActions = Tasks.Select((task) => task.GetOrCreateAction()).ToArray();
4747
var orchestrationAction = new WhenAllAction(compoundActions);
4848
return orchestrationAction;
4949
}

src/DurableEngine/Tasks/WhenAnyTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ internal override Task CreateDTFxTask()
4141

4242
internal override OrchestrationAction CreateOrchestrationAction()
4343
{
44-
var compoundActions = Tasks.Select((task) => task.CreateOrchestrationAction()).ToArray();
44+
var compoundActions = Tasks.Select((task) => task.GetOrCreateAction()).ToArray();
4545
var action = new WhenAnyAction(compoundActions);
4646
return action;
4747
}

0 commit comments

Comments
 (0)