From d99ded151095afb795ef6244c40c5f721d8bfb82 Mon Sep 17 00:00:00 2001 From: Luke Butters Date: Thu, 3 Apr 2025 16:43:31 +1100 Subject: [PATCH 1/2] Allow callers to cancel their request to cancel the script --- source/Octopus.Tentacle.Client/ScriptExecutor.cs | 4 ++-- source/Octopus.Tentacle.Client/Scripts/IScriptExecutor.cs | 2 +- .../Scripts/KubernetesScriptServiceV1Executor.cs | 5 ++--- .../Scripts/ObservingScriptOrchestrator.cs | 3 ++- .../Scripts/ScriptServiceV1Executor.cs | 4 ++-- .../Scripts/ScriptServiceV2Executor.cs | 5 ++--- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/source/Octopus.Tentacle.Client/ScriptExecutor.cs b/source/Octopus.Tentacle.Client/ScriptExecutor.cs index 5e0355343..665e409d3 100644 --- a/source/Octopus.Tentacle.Client/ScriptExecutor.cs +++ b/source/Octopus.Tentacle.Client/ScriptExecutor.cs @@ -60,12 +60,12 @@ public async Task GetStatus(CommandContext comma return await scriptExecutor.GetStatus(commandContext, cancellationToken); } - public async Task CancelScript(CommandContext commandContext) + public async Task CancelScript(CommandContext commandContext, CancellationToken cancellationToken) { var scriptExecutorFactory = CreateScriptExecutorFactory(); var scriptExecutor = scriptExecutorFactory.CreateScriptExecutor(commandContext.ScripServiceVersionUsed); - return await scriptExecutor.CancelScript(commandContext); + return await scriptExecutor.CancelScript(commandContext, cancellationToken); } public async Task CompleteScript(CommandContext commandContext, CancellationToken cancellationToken) diff --git a/source/Octopus.Tentacle.Client/Scripts/IScriptExecutor.cs b/source/Octopus.Tentacle.Client/Scripts/IScriptExecutor.cs index 0544ef9ed..c197029e0 100644 --- a/source/Octopus.Tentacle.Client/Scripts/IScriptExecutor.cs +++ b/source/Octopus.Tentacle.Client/Scripts/IScriptExecutor.cs @@ -30,7 +30,7 @@ Task StartScript(ExecuteScriptCommand command, /// /// The CommandContext from the previous command /// The result, which includes the CommandContext for the next command - Task CancelScript(CommandContext commandContext); + Task CancelScript(CommandContext commandContext, CancellationToken cancellationToken); /// /// Complete the script. diff --git a/source/Octopus.Tentacle.Client/Scripts/KubernetesScriptServiceV1Executor.cs b/source/Octopus.Tentacle.Client/Scripts/KubernetesScriptServiceV1Executor.cs index 20c9d23a9..d817eb70f 100644 --- a/source/Octopus.Tentacle.Client/Scripts/KubernetesScriptServiceV1Executor.cs +++ b/source/Octopus.Tentacle.Client/Scripts/KubernetesScriptServiceV1Executor.cs @@ -153,7 +153,7 @@ async Task GetStatusAction(CancellationToken c return Map(kubernetesScriptStatusResponseV1); } - public async Task CancelScript(CommandContext commandContext) + public async Task CancelScript(CommandContext commandContext, CancellationToken cancellationToken) { async Task CancelScriptAction(CancellationToken ct) { @@ -173,8 +173,7 @@ async Task CancelScriptAction(CancellationToke CancelScriptAction, logger, clientOperationMetricsBuilder, - // We don't want to cancel this operation as it is responsible for stopping the script executing on the Tentacle - CancellationToken.None).ConfigureAwait(false); + cancellationToken).ConfigureAwait(false); return Map(kubernetesScriptStatusResponseV1); } diff --git a/source/Octopus.Tentacle.Client/Scripts/ObservingScriptOrchestrator.cs b/source/Octopus.Tentacle.Client/Scripts/ObservingScriptOrchestrator.cs index 1f71007fa..9ad51f29b 100644 --- a/source/Octopus.Tentacle.Client/Scripts/ObservingScriptOrchestrator.cs +++ b/source/Octopus.Tentacle.Client/Scripts/ObservingScriptOrchestrator.cs @@ -79,7 +79,8 @@ async Task ObserveUntilComplete( { if (scriptExecutionCancellationToken.IsCancellationRequested) { - lastResult = await scriptExecutor.CancelScript(lastResult.ContextForNextCommand).ConfigureAwait(false); + // We don't want to cancel this operation as it is responsible for stopping the script executing on the Tentacle + lastResult = await scriptExecutor.CancelScript(lastResult.ContextForNextCommand, CancellationToken.None).ConfigureAwait(false); } else { diff --git a/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV1Executor.cs b/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV1Executor.cs index 0d2a89dce..a6d8eb953 100644 --- a/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV1Executor.cs +++ b/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV1Executor.cs @@ -106,7 +106,7 @@ public async Task GetStatus(CommandContext comma return Map(scriptStatusResponseV1); } - public async Task CancelScript(CommandContext commandContext) + public async Task CancelScript(CommandContext commandContext, CancellationToken cancellationToken) { var response = await rpcCallExecutor.ExecuteWithNoRetries( RpcCall.Create(nameof(IScriptService.CancelScript)), @@ -119,7 +119,7 @@ public async Task CancelScript(CommandContext co }, logger, clientOperationMetricsBuilder, - CancellationToken.None).ConfigureAwait(false); + cancellationToken).ConfigureAwait(false); return Map(response); } diff --git a/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV2Executor.cs b/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV2Executor.cs index 3564ff1e7..eb4b910e9 100644 --- a/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV2Executor.cs +++ b/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV2Executor.cs @@ -146,7 +146,7 @@ async Task GetStatusAction(CancellationToken ct) return Map(scriptStatusResponseV2); } - public async Task CancelScript(CommandContext commandContext) + public async Task CancelScript(CommandContext commandContext, CancellationToken cancellationToken) { async Task CancelScriptAction(CancellationToken ct) { @@ -166,8 +166,7 @@ async Task CancelScriptAction(CancellationToken ct) CancelScriptAction, logger, clientOperationMetricsBuilder, - // We don't want to cancel this operation as it is responsible for stopping the script executing on the Tentacle - CancellationToken.None).ConfigureAwait(false); + cancellationToken).ConfigureAwait(false); return Map(scriptStatusResponseV2); } From 1e60c41a9d13aae299e539b5e4da3e8c16032f17 Mon Sep 17 00:00:00 2001 From: Luke Butters Date: Fri, 4 Apr 2025 09:35:42 +1100 Subject: [PATCH 2/2] . --- .../ITentacleClient.cs | 20 ++++++++++++------- .../Scripts/ScriptServiceV2Executor.cs | 18 ++++++++--------- .../Octopus.Tentacle.Client/TentacleClient.cs | 16 +++++++-------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/source/Octopus.Tentacle.Client/ITentacleClient.cs b/source/Octopus.Tentacle.Client/ITentacleClient.cs index c79a285fc..128975117 100644 --- a/source/Octopus.Tentacle.Client/ITentacleClient.cs +++ b/source/Octopus.Tentacle.Client/ITentacleClient.cs @@ -34,37 +34,43 @@ Task ExecuteScript( CancellationToken scriptExecutionCancellationToken); /// - /// Start the script. + /// /// + /// + /// + /// + /// Cancels the inflight request /// The result, which includes the CommandContext for the next command Task StartScript(ExecuteScriptCommand command, StartScriptIsBeingReAttempted startScriptIsBeingReAttempted, ITentacleClientTaskLog logger, - CancellationToken scriptExecutionCancellationToken); + CancellationToken requestCancellationToken); + /// /// Get the status. /// /// The CommandContext from the previous command /// - /// + /// Cancels the inflight request /// The result, which includes the CommandContext for the next command - Task GetStatus(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken scriptExecutionCancellationToken); + Task GetStatus(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken requestCancellationToken); /// /// Cancel the script. /// /// The CommandContext from the previous command /// + /// Cancels the inflight request /// The result, which includes the CommandContext for the next command - Task CancelScript(CommandContext commandContext, ITentacleClientTaskLog logger); + Task CancelScript(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken requestCancellationToken); /// /// Complete the script. /// /// The CommandContext from the previous command /// - /// - Task CompleteScript(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken scriptExecutionCancellationToken); + /// Cancels the inflight request + Task CompleteScript(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken requestCancellationToken); } } \ No newline at end of file diff --git a/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV2Executor.cs b/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV2Executor.cs index eb4b910e9..56b22dad2 100644 --- a/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV2Executor.cs +++ b/source/Octopus.Tentacle.Client/Scripts/ScriptServiceV2Executor.cs @@ -67,7 +67,7 @@ static ScriptOperationExecutionResult Map(ScriptStatusResponseV2 scriptStatusRes public async Task StartScript(ExecuteScriptCommand executeScriptCommand, StartScriptIsBeingReAttempted startScriptIsBeingReAttempted, - CancellationToken scriptExecutionCancellationToken) + CancellationToken requestCancellationToken) { var command = Map(executeScriptCommand); ScriptStatusResponseV2 scriptStatusResponse; @@ -98,11 +98,11 @@ void OnErrorAction(Exception ex) OnErrorAction, logger, clientOperationMetricsBuilder, - scriptExecutionCancellationToken).ConfigureAwait(false); + requestCancellationToken).ConfigureAwait(false); return Map(scriptStatusResponse); } - catch (Exception ex) when (scriptExecutionCancellationToken.IsCancellationRequested) + catch (Exception ex) when (requestCancellationToken.IsCancellationRequested) { // If the call to StartScript is in-flight (being transferred to the Service) or we are retrying the StartScript call // then we do not know if the script has been started or not on Tentacle so need to call CancelScript and CompleteScript @@ -126,7 +126,7 @@ void OnErrorAction(Exception ex) - public async Task GetStatus(CommandContext commandContext, CancellationToken scriptExecutionCancellationToken) + public async Task GetStatus(CommandContext commandContext, CancellationToken requestCancellationToken) { async Task GetStatusAction(CancellationToken ct) { @@ -142,11 +142,11 @@ async Task GetStatusAction(CancellationToken ct) GetStatusAction, logger, clientOperationMetricsBuilder, - scriptExecutionCancellationToken).ConfigureAwait(false); + requestCancellationToken).ConfigureAwait(false); return Map(scriptStatusResponseV2); } - public async Task CancelScript(CommandContext commandContext, CancellationToken cancellationToken) + public async Task CancelScript(CommandContext commandContext, CancellationToken requestCancellationToken) { async Task CancelScriptAction(CancellationToken ct) { @@ -166,11 +166,11 @@ async Task CancelScriptAction(CancellationToken ct) CancelScriptAction, logger, clientOperationMetricsBuilder, - cancellationToken).ConfigureAwait(false); + requestCancellationToken).ConfigureAwait(false); return Map(scriptStatusResponseV2); } - public async Task CompleteScript(CommandContext lastStatusResponse, CancellationToken scriptExecutionCancellationToken) + public async Task CompleteScript(CommandContext lastStatusResponse, CancellationToken requestCancellationToken) { try { @@ -179,7 +179,7 @@ async Task CancelScriptAction(CancellationToken ct) using var completeScriptCancellationTokenSource = new CancellationTokenSource(); - await using var _ = scriptExecutionCancellationToken.Register(() => completeScriptCancellationTokenSource.CancelAfter(onCancellationAbandonCompleteScriptAfter)); + await using var _ = requestCancellationToken.Register(() => completeScriptCancellationTokenSource.CancelAfter(onCancellationAbandonCompleteScriptAfter)); await rpcCallExecutor.ExecuteWithNoRetries( RpcCall.Create(nameof(IScriptServiceV2.CompleteScript)), diff --git a/source/Octopus.Tentacle.Client/TentacleClient.cs b/source/Octopus.Tentacle.Client/TentacleClient.cs index ade55f1f6..474d97b22 100644 --- a/source/Octopus.Tentacle.Client/TentacleClient.cs +++ b/source/Octopus.Tentacle.Client/TentacleClient.cs @@ -192,7 +192,7 @@ public async Task StartScript( ExecuteScriptCommand command, StartScriptIsBeingReAttempted startScriptIsBeingReAttempted, ITentacleClientTaskLog logger, - CancellationToken scriptExecutionCancellationToken) + CancellationToken requestCancellationToken) { var scriptExecutor = new ScriptExecutor( allClients, @@ -203,10 +203,10 @@ public async Task StartScript( clientOptions, OnCancellationAbandonCompleteScriptAfter); - return await scriptExecutor.StartScript(command, startScriptIsBeingReAttempted, scriptExecutionCancellationToken); + return await scriptExecutor.StartScript(command, startScriptIsBeingReAttempted, requestCancellationToken); } - public async Task GetStatus(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken scriptExecutionCancellationToken) + public async Task GetStatus(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken requestCancellationToken) { var scriptExecutor = new ScriptExecutor( allClients, @@ -217,10 +217,10 @@ public async Task GetStatus(CommandContext comma clientOptions, OnCancellationAbandonCompleteScriptAfter); - return await scriptExecutor.GetStatus(commandContext, scriptExecutionCancellationToken); + return await scriptExecutor.GetStatus(commandContext, requestCancellationToken); } - public async Task CancelScript(CommandContext commandContext, ITentacleClientTaskLog logger) + public async Task CancelScript(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken requestCancellationToken) { var scriptExecutor = new ScriptExecutor( allClients, @@ -231,10 +231,10 @@ public async Task CancelScript(CommandContext co clientOptions, OnCancellationAbandonCompleteScriptAfter); - return await scriptExecutor.CancelScript(commandContext); + return await scriptExecutor.CancelScript(commandContext, requestCancellationToken); } - public async Task CompleteScript(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken scriptExecutionCancellationToken) + public async Task CompleteScript(CommandContext commandContext, ITentacleClientTaskLog logger, CancellationToken requestCancellationToken) { var scriptExecutor = new ScriptExecutor( allClients, @@ -245,7 +245,7 @@ public async Task CancelScript(CommandContext co clientOptions, OnCancellationAbandonCompleteScriptAfter); - return await scriptExecutor.CompleteScript(commandContext, scriptExecutionCancellationToken); + return await scriptExecutor.CompleteScript(commandContext, requestCancellationToken); } public void Dispose()