@@ -11,58 +11,97 @@ namespace Microsoft.Azure.Functions.PowerShellWorker.Durable
11
11
using System . Linq ;
12
12
using System . Management . Automation ;
13
13
14
- using PowerShellWorker . Utility ;
15
14
using Microsoft . Azure . Functions . PowerShellWorker . Durable . Actions ;
15
+ using Microsoft . Azure . Functions . PowerShellWorker . Utility ;
16
16
17
17
internal class OrchestrationInvoker : IOrchestrationInvoker
18
18
{
19
- public Hashtable Invoke ( OrchestrationBindingInfo orchestrationBindingInfo , IPowerShellServices pwsh )
19
+ private IExternalOrchestrationInvoker externalInvoker ;
20
+
21
+ public Hashtable Invoke (
22
+ OrchestrationBindingInfo orchestrationBindingInfo ,
23
+ IPowerShellServices powerShellServices )
20
24
{
21
25
try
22
26
{
23
- var outputBuffer = new PSDataCollection < object > ( ) ;
24
- var context = orchestrationBindingInfo . Context ;
27
+ if ( powerShellServices . HasExternalDurableSDK ( ) )
28
+ {
29
+ return InvokeExternalDurableSDK ( powerShellServices ) ;
30
+ }
31
+ return InvokeInternalDurableSDK ( orchestrationBindingInfo , powerShellServices ) ;
32
+ }
33
+ catch ( Exception ex )
34
+ {
35
+ ex . Data . Add ( Utils . IsOrchestrationFailureKey , true ) ;
36
+ throw ;
37
+ }
38
+ finally
39
+ {
40
+ powerShellServices . ClearStreamsAndCommands ( ) ;
41
+ }
42
+ }
43
+
44
+ public Hashtable InvokeExternalDurableSDK ( IPowerShellServices powerShellServices )
45
+ {
46
+ return externalInvoker . Invoke ( powerShellServices ) ;
47
+ }
48
+
49
+ public Hashtable InvokeInternalDurableSDK (
50
+ OrchestrationBindingInfo orchestrationBindingInfo ,
51
+ IPowerShellServices powerShellServices )
52
+ {
53
+ var outputBuffer = new PSDataCollection < object > ( ) ;
54
+ var context = orchestrationBindingInfo . Context ;
55
+
56
+ // context.History should never be null when initializing CurrentUtcDateTime
57
+ var orchestrationStart = context . History . First (
58
+ e => e . EventType == HistoryEventType . OrchestratorStarted ) ;
59
+ context . CurrentUtcDateTime = orchestrationStart . Timestamp . ToUniversalTime ( ) ;
25
60
26
- // context.History should never be null when initializing CurrentUtcDateTime
27
- var orchestrationStart = context . History . First (
28
- e => e . EventType == HistoryEventType . OrchestratorStarted ) ;
29
- context . CurrentUtcDateTime = orchestrationStart . Timestamp . ToUniversalTime ( ) ;
61
+ // Marks the first OrchestratorStarted event as processed
62
+ orchestrationStart . IsProcessed = true ;
30
63
31
- // Marks the first OrchestratorStarted event as processed
32
- orchestrationStart . IsProcessed = true ;
33
-
34
- var asyncResult = pwsh . BeginInvoke ( outputBuffer ) ;
64
+ // Finish initializing the Function invocation
65
+ powerShellServices . AddParameter ( orchestrationBindingInfo . ParameterName , context ) ;
66
+ powerShellServices . TracePipelineObject ( ) ;
35
67
36
- var ( shouldStop , actions ) =
37
- orchestrationBindingInfo . Context . OrchestrationActionCollector . WaitForActions ( asyncResult . AsyncWaitHandle ) ;
68
+ var asyncResult = powerShellServices . BeginInvoke ( outputBuffer ) ;
38
69
39
- if ( shouldStop )
70
+ var ( shouldStop , actions ) =
71
+ orchestrationBindingInfo . Context . OrchestrationActionCollector . WaitForActions ( asyncResult . AsyncWaitHandle ) ;
72
+
73
+ if ( shouldStop )
74
+ {
75
+ // The orchestration function should be stopped and restarted
76
+ powerShellServices . StopInvoke ( ) ;
77
+ return CreateOrchestrationResult ( isDone : false , actions , output : null , context . CustomStatus ) ;
78
+ }
79
+ else
80
+ {
81
+ try
40
82
{
41
- // The orchestration function should be stopped and restarted
42
- pwsh . StopInvoke ( ) ;
43
- return CreateOrchestrationResult ( isDone : false , actions , output : null , context . CustomStatus ) ;
83
+ // The orchestration function completed
84
+ powerShellServices . EndInvoke ( asyncResult ) ;
85
+ var result = CreateReturnValueFromFunctionOutput ( outputBuffer ) ;
86
+ return CreateOrchestrationResult ( isDone : true , actions , output : result , context . CustomStatus ) ;
44
87
}
45
- else
88
+ catch ( Exception e )
46
89
{
47
- try
48
- {
49
- // The orchestration function completed
50
- pwsh . EndInvoke ( asyncResult ) ;
51
- var result = FunctionReturnValueBuilder . CreateReturnValueFromFunctionOutput ( outputBuffer ) ;
52
- return CreateOrchestrationResult ( isDone : true , actions , output : result , context . CustomStatus ) ;
53
- }
54
- catch ( Exception e )
55
- {
56
- // The orchestrator code has thrown an unhandled exception:
57
- // this should be treated as an entire orchestration failure
58
- throw new OrchestrationFailureException ( actions , context . CustomStatus , e ) ;
59
- }
90
+ // The orchestrator code has thrown an unhandled exception:
91
+ // this should be treated as an entire orchestration failure
92
+ throw new OrchestrationFailureException ( actions , context . CustomStatus , e ) ;
60
93
}
61
94
}
62
- finally
95
+ }
96
+
97
+ public static object CreateReturnValueFromFunctionOutput ( IList < object > pipelineItems )
98
+ {
99
+ if ( pipelineItems == null || pipelineItems . Count <= 0 )
63
100
{
64
- pwsh . ClearStreamsAndCommands ( ) ;
101
+ return null ;
65
102
}
103
+
104
+ return pipelineItems . Count == 1 ? pipelineItems [ 0 ] : pipelineItems . ToArray ( ) ;
66
105
}
67
106
68
107
private static Hashtable CreateOrchestrationResult (
@@ -74,5 +113,10 @@ private static Hashtable CreateOrchestrationResult(
74
113
var orchestrationMessage = new OrchestrationMessage ( isDone , actions , output , customStatus ) ;
75
114
return new Hashtable { { AzFunctionInfo . DollarReturn , orchestrationMessage } } ;
76
115
}
116
+
117
+ public void SetExternalInvoker ( IExternalOrchestrationInvoker externalInvoker )
118
+ {
119
+ this . externalInvoker = externalInvoker ;
120
+ }
77
121
}
78
122
}
0 commit comments