@@ -11,58 +11,97 @@ namespace Microsoft.Azure.Functions.PowerShellWorker.Durable
1111 using System . Linq ;
1212 using System . Management . Automation ;
1313
14- using PowerShellWorker . Utility ;
1514 using Microsoft . Azure . Functions . PowerShellWorker . Durable . Actions ;
15+ using Microsoft . Azure . Functions . PowerShellWorker . Utility ;
1616
1717 internal class OrchestrationInvoker : IOrchestrationInvoker
1818 {
19- public Hashtable Invoke ( OrchestrationBindingInfo orchestrationBindingInfo , IPowerShellServices pwsh )
19+ private IExternalOrchestrationInvoker externalInvoker ;
20+
21+ public Hashtable Invoke (
22+ OrchestrationBindingInfo orchestrationBindingInfo ,
23+ IPowerShellServices powerShellServices )
2024 {
2125 try
2226 {
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 ( ) ;
2560
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 ;
3063
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 ( ) ;
3567
36- var ( shouldStop , actions ) =
37- orchestrationBindingInfo . Context . OrchestrationActionCollector . WaitForActions ( asyncResult . AsyncWaitHandle ) ;
68+ var asyncResult = powerShellServices . BeginInvoke ( outputBuffer ) ;
3869
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
4082 {
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 ) ;
4487 }
45- else
88+ catch ( Exception e )
4689 {
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 ) ;
6093 }
6194 }
62- finally
95+ }
96+
97+ public static object CreateReturnValueFromFunctionOutput ( IList < object > pipelineItems )
98+ {
99+ if ( pipelineItems == null || pipelineItems . Count <= 0 )
63100 {
64- pwsh . ClearStreamsAndCommands ( ) ;
101+ return null ;
65102 }
103+
104+ return pipelineItems . Count == 1 ? pipelineItems [ 0 ] : pipelineItems . ToArray ( ) ;
66105 }
67106
68107 private static Hashtable CreateOrchestrationResult (
@@ -74,5 +113,10 @@ private static Hashtable CreateOrchestrationResult(
74113 var orchestrationMessage = new OrchestrationMessage ( isDone , actions , output , customStatus ) ;
75114 return new Hashtable { { AzFunctionInfo . DollarReturn , orchestrationMessage } } ;
76115 }
116+
117+ public void SetExternalInvoker ( IExternalOrchestrationInvoker externalInvoker )
118+ {
119+ this . externalInvoker = externalInvoker ;
120+ }
77121 }
78122}
0 commit comments