Skip to content

Commit d3d100e

Browse files
committed
support external cancellationToken
1 parent 72746d6 commit d3d100e

File tree

3 files changed

+53
-33
lines changed

3 files changed

+53
-33
lines changed

sandbox/GeneratorSandbox/Program.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,25 @@
4747

4848
var app = builder.ToConsoleAppBuilder();
4949

50+
var consoleAppLoger = ConsoleApp.ServiceProvider.GetRequiredService<ILogger<Program>>(); // already built service provider.
51+
ConsoleApp.Log = msg => consoleAppLoger.LogDebug(msg);
52+
ConsoleApp.LogError = msg => consoleAppLoger.LogError(msg);
53+
5054
app.UseFilter<CommandTracingFilter>();
5155

52-
app.Add("", async ([FromServices] ILogger<Program> logger) =>
56+
app.Add("", async ([FromServices] ILogger<Program> logger/*, CancellationToken cancellationToken*/) =>
5357
{
58+
var cancellationToken = CancellationToken.None;
59+
5460
using var httpClient = new HttpClient();
55-
var ms = await httpClient.GetStringAsync("https://www.microsoft.com");
61+
var ms = await httpClient.GetStringAsync("https://www.microsoft.com", cancellationToken);
5662
logger.LogInformation(ms);
57-
var google = await httpClient.GetStringAsync("https://www.google.com");
63+
var google = await httpClient.GetStringAsync("https://www.google.com", cancellationToken);
5864
logger.LogInformation(google);
5965

60-
var ms2 = httpClient.GetStringAsync("https://www.microsoft.com");
61-
var google2 = httpClient.GetStringAsync("https://www.google.com");
62-
var apple2 = httpClient.GetStringAsync("https://www.apple.com");
66+
var ms2 = httpClient.GetStringAsync("https://www.microsoft.com", cancellationToken);
67+
var google2 = httpClient.GetStringAsync("https://www.google.com", cancellationToken);
68+
var apple2 = httpClient.GetStringAsync("https://www.apple.com", cancellationToken);
6369
await Task.WhenAll(ms2, google2, apple2);
6470

6571
logger.LogInformation(apple2.Result);
@@ -100,8 +106,15 @@ public override async Task InvokeAsync(ConsoleAppContext context, CancellationTo
100106
{
101107
if (activity != null)
102108
{
103-
activity.AddException(ex);
104-
activity.SetStatus(ActivityStatusCode.Error);
109+
if (ex is OperationCanceledException)
110+
{
111+
activity.SetStatus(ActivityStatusCode.Error, "Canceled");
112+
}
113+
else
114+
{
115+
activity.AddException(ex);
116+
activity.SetStatus(ActivityStatusCode.Error);
117+
}
105118
}
106119
throw;
107120
}

src/ConsoleAppFramework/ConsoleAppBaseCode.cs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,9 @@ static void ShowVersion()
371371
372372
static partial void ShowHelp(int helpId);
373373
374-
static async Task RunWithFilterAsync(string commandName, string[] args, int commandDepth, int escapeIndex, ConsoleAppFilter invoker)
374+
static async Task RunWithFilterAsync(string commandName, string[] args, int commandDepth, int escapeIndex, ConsoleAppFilter invoker, CancellationToken cancellationToken)
375375
{
376-
using var posixSignalHandler = PosixSignalHandler.Register(Timeout);
376+
using var posixSignalHandler = PosixSignalHandler.Register(Timeout, cancellationToken);
377377
try
378378
{
379379
await Task.Run(() => invoker.InvokeAsync(new ConsoleAppContext(commandName, args, null, commandDepth, escapeIndex), posixSignalHandler.Token)).WaitAsync(posixSignalHandler.TimeoutToken);
@@ -411,16 +411,16 @@ sealed class PosixSignalHandler : IDisposable
411411
PosixSignalRegistration? sigQuit;
412412
PosixSignalRegistration? sigTerm;
413413
414-
PosixSignalHandler(TimeSpan timeout)
414+
PosixSignalHandler(TimeSpan timeout, CancellationToken cancellationToken)
415415
{
416-
this.cancellationTokenSource = new CancellationTokenSource();
416+
this.cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
417417
this.timeoutCancellationTokenSource = new CancellationTokenSource();
418418
this.timeout = timeout;
419419
}
420420
421-
public static PosixSignalHandler Register(TimeSpan timeout)
421+
public static PosixSignalHandler Register(TimeSpan timeout, CancellationToken cancellationToken)
422422
{
423-
var handler = new PosixSignalHandler(timeout);
423+
var handler = new PosixSignalHandler(timeout, cancellationToken);
424424
425425
Action<PosixSignalContext> handleSignal = handler.HandlePosixSignal;
426426
@@ -443,6 +443,7 @@ public void Dispose()
443443
sigInt?.Dispose();
444444
sigQuit?.Dispose();
445445
sigTerm?.Dispose();
446+
cancellationTokenSource.Dispose();
446447
timeoutCancellationTokenSource.Dispose();
447448
}
448449
}
@@ -482,10 +483,10 @@ public void UseFilter<T>() where T : ConsoleAppFilter { }
482483
partial void AddCore(string commandName, Delegate command);
483484
484485
[MethodImpl(MethodImplOptions.AggressiveInlining)]
485-
partial void RunCore(string[] args);
486+
partial void RunCore(string[] args, CancellationToken cancellationToken);
486487
487488
[MethodImpl(MethodImplOptions.AggressiveInlining)]
488-
partial void RunAsyncCore(string[] args, ref Task result);
489+
partial void RunAsyncCore(string[] args, CancellationToken cancellationToken, ref Task result);
489490
490491
partial void BuildAndSetServiceProvider();
491492
@@ -546,15 +547,14 @@ internal static partial class ConsoleApp
546547
internal partial class ConsoleAppBuilder
547548
{
548549
public void Run(string[] args) => Run(args, true);
550+
public void Run(string[] args, CancellationToken cancellationToken) => Run(args, true, cancellationToken);
549551
550-
public Task RunAsync(string[] args) => RunAsync(args, true);
551-
552-
public void Run(string[] args, bool disposeService)
552+
public void Run(string[] args, bool disposeService, CancellationToken cancellationToken = default)
553553
{
554554
BuildAndSetServiceProvider();
555555
try
556556
{
557-
RunCore(args);
557+
RunCore(args, cancellationToken);
558558
}
559559
finally
560560
{
@@ -568,13 +568,16 @@ public void Run(string[] args, bool disposeService)
568568
}
569569
}
570570
571-
public async Task RunAsync(string[] args, bool disposeService)
571+
public Task RunAsync(string[] args) => RunAsync(args, true);
572+
public Task RunAsync(string[] args, CancellationToken cancellationToken) => RunAsync(args, true, cancellationToken);
573+
574+
public async Task RunAsync(string[] args, bool disposeService, CancellationToken cancellationToken = default)
572575
{
573576
BuildAndSetServiceProvider();
574577
try
575578
{
576579
Task? task = null;
577-
RunAsyncCore(args, ref task!);
580+
RunAsyncCore(args, cancellationToken, ref task!);
578581
if (task != null)
579582
{
580583
await task;
@@ -621,8 +624,9 @@ internal static partial class ConsoleApp
621624
internal partial class ConsoleAppBuilder
622625
{
623626
public void Run(string[] args) => Run(args, true, true, true);
627+
public void Run(string[] args, CancellationToken cancellationToken) => Run(args, true, true, true, cancellationToken);
624628
625-
public void Run(string[] args, bool startHost, bool stopHost, bool disposeService)
629+
public void Run(string[] args, bool startHost, bool stopHost, bool disposeService, CancellationToken cancellationToken = default)
626630
{
627631
BuildAndSetServiceProvider();
628632
Microsoft.Extensions.Hosting.IHost? host = ConsoleApp.ServiceProvider?.GetService(typeof(Microsoft.Extensions.Hosting.IHost)) as Microsoft.Extensions.Hosting.IHost;
@@ -632,7 +636,7 @@ public void Run(string[] args, bool startHost, bool stopHost, bool disposeServic
632636
{
633637
host?.StartAsync().GetAwaiter().GetResult();
634638
}
635-
RunCore(args);
639+
RunCore(args, cancellationToken);
636640
}
637641
finally
638642
{
@@ -651,8 +655,9 @@ public void Run(string[] args, bool startHost, bool stopHost, bool disposeServic
651655
}
652656
653657
public Task RunAsync(string[] args) => RunAsync(args, true, true, true);
658+
public Task RunAsync(string[] args, CancellationToken cancellationToken) => RunAsync(args, true, true, true, cancellationToken);
654659
655-
public async Task RunAsync(string[] args, bool startHost, bool stopHost, bool disposeService)
660+
public async Task RunAsync(string[] args, bool startHost, bool stopHost, bool disposeService, CancellationToken cancellationToken = default)
656661
{
657662
BuildAndSetServiceProvider();
658663
Microsoft.Extensions.Hosting.IHost? host = ConsoleApp.ServiceProvider?.GetService(typeof(Microsoft.Extensions.Hosting.IHost)) as Microsoft.Extensions.Hosting.IHost;
@@ -663,7 +668,7 @@ public async Task RunAsync(string[] args, bool startHost, bool stopHost, bool di
663668
await host?.StartAsync();
664669
}
665670
Task? task = null;
666-
RunAsyncCore(args, ref task!);
671+
RunAsyncCore(args, cancellationToken, ref task!);
667672
if (task != null)
668673
{
669674
await task;

src/ConsoleAppFramework/Emitter.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ public void EmitRun(SourceBuilder sb, CommandWithId commandWithId, bool isRunAsy
4242
}
4343

4444
var commandDepthEscapeIndex = emitForBuilder ? ", int commandDepth, int escapeIndex" : "";
45-
var filterCancellationToken = command.HasFilter ? ", ConsoleAppContext context, CancellationToken cancellationToken" : "";
45+
var filterCancellationToken = command.HasFilter ? ", ConsoleAppContext context, CancellationToken cancellationToken"
46+
: emitForBuilder ? ", CancellationToken __ExternalCancellationToken__"
47+
: "";
4648

4749
if (!emitForBuilder)
4850
{
@@ -83,7 +85,7 @@ public void EmitRun(SourceBuilder sb, CommandWithId commandWithId, bool isRunAsy
8385
// prepare argument variables
8486
if (hasCancellationToken)
8587
{
86-
sb.AppendLine("using var posixSignalHandler = PosixSignalHandler.Register(Timeout);");
88+
sb.AppendLine("using var posixSignalHandler = PosixSignalHandler.Register(Timeout, __ExternalCancellationToken__);");
8789
}
8890
if (hasConsoleAppContext)
8991
{
@@ -412,7 +414,7 @@ public void EmitBuilder(SourceBuilder sb, CommandWithId[] commandIds, bool emitS
412414
if (emitSync)
413415
{
414416
sb.AppendLine();
415-
using (sb.BeginBlock("partial void RunCore(string[] args)"))
417+
using (sb.BeginBlock("partial void RunCore(string[] args, CancellationToken cancellationToken)"))
416418
{
417419
if (hasRootCommand)
418420
{
@@ -431,7 +433,7 @@ public void EmitBuilder(SourceBuilder sb, CommandWithId[] commandIds, bool emitS
431433
if (emitAsync)
432434
{
433435
sb.AppendLine();
434-
using (sb.BeginBlock("partial void RunAsyncCore(string[] args, ref Task result)"))
436+
using (sb.BeginBlock("partial void RunAsyncCore(string[] args, CancellationToken cancellationToken, ref Task result)"))
435437
{
436438
if (hasRootCommand)
437439
{
@@ -559,16 +561,16 @@ void EmitLeafCommand(CommandWithId? command)
559561
{
560562
if (!isRunAsync)
561563
{
562-
sb.AppendLine($"RunCommand{command.Id}(args, {depth}, args.AsSpan().IndexOf(\"--\"){commandArgs});");
564+
sb.AppendLine($"RunCommand{command.Id}(args, {depth}, args.AsSpan().IndexOf(\"--\"){commandArgs}, cancellationToken);");
563565
}
564566
else
565567
{
566-
sb.AppendLine($"result = RunCommand{command.Id}Async(args, {depth}, args.AsSpan().IndexOf(\"--\"){commandArgs});");
568+
sb.AppendLine($"result = RunCommand{command.Id}Async(args, {depth}, args.AsSpan().IndexOf(\"--\"){commandArgs}, cancellationToken);");
567569
}
568570
}
569571
else
570572
{
571-
var invokeCode = $"RunWithFilterAsync(\"{command.Command.Name}\", args, {depth}, args.AsSpan().IndexOf(\"--\"), new Command{command.Id}Invoker({commandArgs.TrimStart(',', ' ')}).BuildFilter())";
573+
var invokeCode = $"RunWithFilterAsync(\"{command.Command.Name}\", args, {depth}, args.AsSpan().IndexOf(\"--\"), new Command{command.Id}Invoker({commandArgs.TrimStart(',', ' ')}).BuildFilter(), cancellationToken)";
572574
if (!isRunAsync)
573575
{
574576
sb.AppendLine($"{invokeCode}.GetAwaiter().GetResult();");

0 commit comments

Comments
 (0)