Skip to content

Commit 4552432

Browse files
authored
refactor: convert orchestrator to async (#240)
1 parent f246185 commit 4552432

File tree

3 files changed

+48
-38
lines changed

3 files changed

+48
-38
lines changed

src/Microsoft.ComponentDetection.Common/Telemetry/Records/BcdeExecutionTelemetryRecord.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace Microsoft.ComponentDetection.Common.Telemetry.Records
44
{
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
58
public class BcdeExecutionTelemetryRecord : BaseDetectionTelemetryRecord
69
{
710
public override string RecordName => "BcdeExecution";
@@ -22,13 +25,16 @@ public class BcdeExecutionTelemetryRecord : BaseDetectionTelemetryRecord
2225

2326
public string AgentOSDescription { get; set; }
2427

25-
public static TReturn Track<TReturn>(Func<BcdeExecutionTelemetryRecord, TReturn> functionToTrack, bool terminalRecord = false)
28+
public static async Task<TReturn> TrackAsync<TReturn>(
29+
Func<BcdeExecutionTelemetryRecord, CancellationToken, Task<TReturn>> functionToTrack,
30+
bool terminalRecord = false,
31+
CancellationToken cancellationToken = default)
2632
{
2733
using var record = new BcdeExecutionTelemetryRecord();
2834

2935
try
3036
{
31-
return functionToTrack(record);
37+
return await functionToTrack(record, cancellationToken);
3238
}
3339
catch (Exception ex)
3440
{

src/Microsoft.ComponentDetection.Orchestrator/Orchestrator.cs

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class Orchestrator
2727
{
2828
private static readonly bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
2929

30-
public ScanResult Load(string[] args)
30+
public async Task<ScanResult> LoadAsync(string[] args, CancellationToken cancellationToken = default)
3131
{
3232
var argumentHelper = new ArgumentHelper { ArgumentSets = new[] { new BaseArguments() } };
3333
BaseArguments baseArguments = null;
@@ -65,19 +65,20 @@ public ScanResult Load(string[] args)
6565
var shouldFailureBeSuppressed = false;
6666

6767
// Don't use the using pattern here so we can take care not to clobber the stack
68-
var returnResult = BcdeExecutionTelemetryRecord.Track(
69-
(record) =>
70-
{
71-
var executionResult = this.HandleCommand(args, record);
72-
if (executionResult.ResultCode == ProcessingResultCode.PartialSuccess)
68+
var returnResult = await BcdeExecutionTelemetryRecord.TrackAsync(
69+
async (record, ct) =>
7370
{
74-
shouldFailureBeSuppressed = true;
75-
record.HiddenExitCode = (int)executionResult.ResultCode;
76-
}
71+
var executionResult = await this.HandleCommandAsync(args, record, ct);
72+
if (executionResult.ResultCode == ProcessingResultCode.PartialSuccess)
73+
{
74+
shouldFailureBeSuppressed = true;
75+
record.HiddenExitCode = (int)executionResult.ResultCode;
76+
}
7777

78-
return executionResult;
79-
},
80-
true);
78+
return executionResult;
79+
},
80+
true,
81+
cancellationToken);
8182

8283
// The order of these things is a little weird, but done this way mostly to prevent any of the logic inside if blocks from being duplicated
8384
if (shouldFailureBeSuppressed)
@@ -126,35 +127,38 @@ private static void AddAssembliesWithType<T>(Assembly assembly, ContainerConfigu
126127
[Import]
127128
private static IArgumentHelper ArgumentHelper { get; set; }
128129

129-
public ScanResult HandleCommand(string[] args, BcdeExecutionTelemetryRecord telemetryRecord)
130+
public async Task<ScanResult> HandleCommandAsync(
131+
string[] args,
132+
BcdeExecutionTelemetryRecord telemetryRecord,
133+
CancellationToken cancellationToken = default)
130134
{
131135
var scanResult = new ScanResult()
132136
{
133137
ResultCode = ProcessingResultCode.Error,
134138
};
135139

136-
var parsedArguments = ArgumentHelper.ParseArguments(args)
137-
.WithParsed<IScanArguments>(argumentSet =>
138-
{
139-
CommandLineArgumentsExporter.ArgumentsForDelayedInjection = argumentSet;
140+
var parsedArguments = ArgumentHelper.ParseArguments(args);
141+
await parsedArguments.WithParsedAsync<IScanArguments>(async argumentSet =>
142+
{
143+
CommandLineArgumentsExporter.ArgumentsForDelayedInjection = argumentSet;
140144

141-
// Don't set production telemetry if we are running the build task in DevFabric. 0.36.0 is set in the task.json for the build task in development, but is calculated during deployment for production.
142-
TelemetryConstants.CorrelationId = argumentSet.CorrelationId;
143-
telemetryRecord.Command = this.GetVerb(argumentSet);
145+
// Don't set production telemetry if we are running the build task in DevFabric. 0.36.0 is set in the task.json for the build task in development, but is calculated during deployment for production.
146+
TelemetryConstants.CorrelationId = argumentSet.CorrelationId;
147+
telemetryRecord.Command = this.GetVerb(argumentSet);
144148

145-
scanResult = this.SafelyExecute(telemetryRecord, () =>
146-
{
147-
this.GenerateEnvironmentSpecificTelemetry(telemetryRecord);
149+
scanResult = await this.SafelyExecuteAsync(telemetryRecord, async () =>
150+
{
151+
await this.GenerateEnvironmentSpecificTelemetryAsync(telemetryRecord);
148152

149-
telemetryRecord.Arguments = JsonConvert.SerializeObject(argumentSet);
150-
FileWritingService.Init(argumentSet.Output);
151-
Logger.Init(argumentSet.Verbosity);
152-
Logger.LogInfo($"Run correlation id: {TelemetryConstants.CorrelationId.ToString()}");
153+
telemetryRecord.Arguments = JsonConvert.SerializeObject(argumentSet);
154+
FileWritingService.Init(argumentSet.Output);
155+
Logger.Init(argumentSet.Verbosity);
156+
Logger.LogInfo($"Run correlation id: {TelemetryConstants.CorrelationId.ToString()}");
153157

154-
return this.Dispatch(argumentSet, CancellationToken.None).GetAwaiter().GetResult();
155-
});
156-
})
157-
.WithNotParsed(errors =>
158+
return await this.Dispatch(argumentSet, cancellationToken);
159+
});
160+
});
161+
parsedArguments.WithNotParsed(errors =>
158162
{
159163
if (errors.Any(e => e is HelpVerbRequestedError))
160164
{
@@ -174,7 +178,7 @@ public ScanResult HandleCommand(string[] args, BcdeExecutionTelemetryRecord tele
174178
return scanResult;
175179
}
176180

177-
private void GenerateEnvironmentSpecificTelemetry(BcdeExecutionTelemetryRecord telemetryRecord)
181+
private async Task GenerateEnvironmentSpecificTelemetryAsync(BcdeExecutionTelemetryRecord telemetryRecord)
178182
{
179183
telemetryRecord.AgentOSDescription = RuntimeInformation.OSDescription;
180184

@@ -204,7 +208,7 @@ private void GenerateEnvironmentSpecificTelemetry(BcdeExecutionTelemetryRecord t
204208
throw new TimeoutException($"The execution did not complete in the alotted time ({taskTimeout} seconds) and has been terminated prior to completion");
205209
}
206210

207-
agentOSMeaningfulDetails[LibSslDetailsKey] = getLibSslPackages.GetAwaiter().GetResult();
211+
agentOSMeaningfulDetails[LibSslDetailsKey] = await getLibSslPackages;
208212
}
209213
catch (Exception ex)
210214
{
@@ -259,11 +263,11 @@ private async Task<ScanResult> Dispatch(IScanArguments arguments, CancellationTo
259263
return scanResult;
260264
}
261265

262-
private ScanResult SafelyExecute(BcdeExecutionTelemetryRecord record, Func<ScanResult> wrappedInvocation)
266+
private async Task<ScanResult> SafelyExecuteAsync(BcdeExecutionTelemetryRecord record, Func<Task<ScanResult>> wrappedInvocation)
263267
{
264268
try
265269
{
266-
return wrappedInvocation();
270+
return await wrappedInvocation();
267271
}
268272
catch (Exception ae)
269273
{

src/Microsoft.ComponentDetection/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static async Task Main(string[] args)
2929

3030
var orchestrator = new Orchestrator.Orchestrator();
3131

32-
var result = orchestrator.Load(args);
32+
var result = await orchestrator.LoadAsync(args);
3333

3434
var exitCode = (int)result.ResultCode;
3535
if (result.ResultCode == ProcessingResultCode.Error || result.ResultCode == ProcessingResultCode.InputError)

0 commit comments

Comments
 (0)