Skip to content

Commit b44cdc1

Browse files
committed
Added Invocation ID to SetFunctionInvocationContextCommand and added a call to Get-CurrentActivityForInvocation
1 parent 46daa71 commit b44cdc1

File tree

6 files changed

+69
-31
lines changed

6 files changed

+69
-31
lines changed

src/DurableSDK/Commands/SetFunctionInvocationContextCommand.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class SetFunctionInvocationContextCommand : PSCmdlet
1818
{
1919
internal const string ContextKey = "OrchestrationContext";
2020
private const string DurableClientKey = "DurableClient";
21+
private const string InvocationIdKey = "InvocationId";
2122

2223
[Parameter(Mandatory = true, ParameterSetName = ContextKey)]
2324
public OrchestrationContext OrchestrationContext { get; set; }
@@ -28,6 +29,12 @@ public class SetFunctionInvocationContextCommand : PSCmdlet
2829
[Parameter(Mandatory = true, ParameterSetName = DurableClientKey)]
2930
public object DurableClient { get; set; }
3031

32+
/// <summary>
33+
/// The invocation id.
34+
/// </summary>
35+
[Parameter(Mandatory = true, ParameterSetName = InvocationIdKey)]
36+
public string InvocationId { get; set; }
37+
3138
[Parameter(Mandatory = true, ParameterSetName = "Clear")]
3239
public SwitchParameter Clear { get; set; }
3340

@@ -44,11 +51,16 @@ protected override void EndProcessing()
4451
privateData[DurableClientKey] = DurableClient;
4552
break;
4653

54+
case InvocationIdKey:
55+
privateData[InvocationIdKey] = InvocationId;
56+
break;
57+
4758
default:
4859
if (Clear.IsPresent)
4960
{
5061
privateData.Remove(ContextKey);
5162
privateData.Remove(DurableClientKey);
63+
privateData.Remove(InvocationIdKey);
5264
}
5365
break;
5466
}

src/DurableSDK/IPowerShellServices.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ internal interface IPowerShellServices
2121

2222
void SetDurableClient(object durableClient);
2323

24+
void SetInvocationId(string invocationId);
25+
2426
OrchestrationBindingInfo SetOrchestrationContext(ParameterBinding context, out IExternalOrchestrationInvoker externalInvoker);
2527

2628
void ClearOrchestrationContext();

src/DurableSDK/PowerShellServices.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ public void SetDurableClient(object durableClient)
7272
_hasInitializedDurableFunctions = true;
7373
}
7474

75+
public void SetInvocationId(string invocationId)
76+
{
77+
_pwsh.AddCommand(SetFunctionInvocationContextCommand)
78+
.AddParameter("InvocationId", invocationId)
79+
.InvokeAndClearCommands();
80+
}
81+
7582
public OrchestrationBindingInfo SetOrchestrationContext(
7683
ParameterBinding context,
7784
out IExternalOrchestrationInvoker externalInvoker)

src/DurableWorker/DurableController.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private void tryEnablingExternalSDK()
8585
}
8686
}
8787

88-
public void InitializeBindings(IList<ParameterBinding> inputData, out bool hasExternalSDK)
88+
public void InitializeBindings(IList<ParameterBinding> inputData, out bool hasExternalSDK, string invocationId = "")
8989
{
9090
this.tryEnablingExternalSDK();
9191

@@ -121,6 +121,7 @@ public void InitializeBindings(IList<ParameterBinding> inputData, out bool hasEx
121121
_orchestrationInvoker.SetExternalInvoker(externalInvoker);
122122
}
123123
hasExternalSDK = _powerShellServices.HasExternalDurableSDK();
124+
_powerShellServices.SetInvocationId(invocationId);
124125
}
125126

126127
public void AfterFunctionInvocation()

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

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ function GetDurableClientFromModulePrivateData {
1919
}
2020
}
2121

22+
function GetInvocationIdFromModulePrivateData {
23+
$PrivateData = $PSCmdlet.MyInvocation.MyCommand.Module.PrivateData
24+
if ($null -eq $PrivateData -or $null -eq $PrivateData['InvocationId']) {
25+
return $null
26+
}
27+
else {
28+
return $PrivateData['InvocationId']
29+
}
30+
}
31+
2232
function Get-DurableStatus {
2333
[CmdletBinding()]
2434
param(
@@ -121,6 +131,9 @@ function Start-DurableOrchestration {
121131
$InstanceId = (New-Guid).Guid
122132
}
123133

134+
$invocationId = GetInvocationIdFromModulePrivateData
135+
$headers = Get-TraceHeaders -InvocationId $invocationId
136+
124137
$Uri =
125138
if ($DurableClient.rpcBaseUrl) {
126139
# Fast local RPC path
@@ -133,44 +146,47 @@ function Start-DurableOrchestration {
133146

134147
$Body = $InputObject | ConvertTo-Json -Compress
135148

136-
$invokeParams = @{
137-
Uri = $Uri
138-
Method = 'POST'
139-
ContentType = 'application/json'
140-
Body = $Body
141-
}
149+
$null = Invoke-RestMethod -Uri $Uri -Method 'POST' -ContentType 'application/json' -Body $Body -Headers $headers
150+
151+
return $instanceId
152+
}
142153

143-
try {
144-
$activity = Start-FunctionsOpenTelemetrySpan -ActivityName "Starting orchestration"
154+
function Get-TraceHeaders {
155+
param(
156+
[string] $InvocationId
157+
)
158+
159+
if ($null -eq $InvocationId -or $InvocationId -eq "") {
160+
return @{} # Return an empty headers object
161+
}
145162

146-
$traceId = $activity.activity.TraceId
147-
$spanId = $activity.activity.SpanId
163+
# Check if Get-CurrentActivityForInvocation is available
164+
if (-not (Get-Command -Name Get-CurrentActivityForInvocation -ErrorAction SilentlyContinue)) {
165+
Write-Warning "Get-CurrentActivityForInvocation is not available. Skipping call."
166+
return @{} # Return an empty headers object
167+
}
148168

149-
# Construct the traceparent header
150-
$traceParent = "00-$traceId-$spanId-01"
169+
$activityResponse = Get-CurrentActivityForInvocation -InvocationId $invocationId
170+
$activity = $activityResponse.activity
151171

152-
$traceState = $activity.activity.TraceState
172+
$traceId = $activity.TraceId
173+
$spanId = $activity.SpanId
174+
$traceFlags = $activity.TraceFlags
175+
$traceState = $activity.TraceStateString
153176

154-
$invokeParams.Headers = @{
155-
'traceparent' = $traceParent
156-
'tracestate' = $traceState
157-
}
158-
# Do whatever you need to do with the trace information using the activity here
159-
} catch {
160-
# Do something better - correctly handle errors when the OTel SDK is not available
161-
# Output errors from this command in a reasonable way
162-
# Detect if calling Stop-FunctionsOpenTelemetrySpan is necessary and change that logic too
177+
$flag = "00"
178+
if ($null -ne $traceFlags -and $traceFlags -eq "Recorded") {
179+
$flag = "01"
163180
}
164-
165-
$null = Invoke-RestMethod @invokeParams
166181

167-
try {
168-
Stop-FunctionsOpenTelemetrySpan -Activity $activity
169-
} catch {
170-
# Do something better here
182+
$traceparent = "00-$traceId-$spanId-$flag"
183+
184+
$headers = @{
185+
"traceparent" = $traceparent
186+
"tracestate" = $traceState
171187
}
172188

173-
return $instanceId
189+
return $headers
174190
}
175191

176192
function Stop-DurableOrchestration {

src/PowerShell/PowerShellManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public Hashtable InvokeFunction(
215215

216216
try
217217
{
218-
durableFunctionsUtils.InitializeBindings(inputData, out bool hasExternalDFsdk);
218+
durableFunctionsUtils.InitializeBindings(inputData: inputData, invocationId: otelContext.InvocationId, hasExternalSDK: out bool hasExternalDFsdk);
219219
Logger.Log(isUserOnlyLog: false, LogLevel.Trace, String.Format(PowerShellWorkerStrings.UtilizingExternalDurableSDK, hasExternalDFsdk));
220220

221221
ImportEntryPointModule(functionInfo);

0 commit comments

Comments
 (0)