如何在 Durable Functions 中中止 [ActivityTrigger] 函数
How to abort [ActivityTrigger] function in Durable Functions
我有一个 [DurableOrchestrationClient],它启动一个 [OrchestrationTrigger],它启动一个长 运行 [ActivityTrigger] 函数。
我知道如何使用 TerminateAsync() 来终止来自 运行 的 [OrchestrationTrigger]。
问题是当我终止 [OrchestrationTrigger] 函数时 [ActivityTrigger] 没有中止。 [ActivityTrigger] 保持 运行 直到完成。
当我调用 TerminateAsync() 时,我需要一种方法来中止长 运行 [ActivityTrigger]。
我的猜测是我可以将 CancellationToken 传递给 [ActivityTrigger] 函数,然后检查 cancellationToken.IsCancellationRequested 以中止。
但如何做到这一点?
这里是测试代码
[FunctionName("A_ProcessPayment")]
public static async Task<processTracker> A_ProcessPayment(
[ActivityTrigger] DurableActivityContext context,
TraceWriter log,
CancellationToken cancellationToken)
{
processTracker p = context.GetInput<processTracker>();
try
{
for (int i = 0; i < 5; i++){
if (cancellationToken.IsCancellationRequested) // This is always false!
{
break;
}
Trace.WriteLine("Long task loop: " + i);
await Task.Delay(10000);
}
}
catch (OperationCanceledException) {
log.Warning("C# HTTP trigger function canceled.");
return p;
}
Trace.WriteLine("Long task DONE");
return p;
}
更新:
您可以选择将令牌作为对象传递给 Activity 触发器,如下所示:
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
namespace OrchesterTrigger
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var outputs = new List<string>();
string mytoken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
outputs.Add(await context.CallActivityAsync<string>("Function1", mytoken));
return outputs;
}
[FunctionName("Function1")]
public static string SayHello([ActivityTrigger] string mytoken, ILogger log)
{
log.LogInformation($"Mytoken is {mytoken}.=======================================");
return $"Mytoken is {mytoken}!";
}
[FunctionName("Function1_HttpStart")]
public static async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
[OrchestrationClient]DurableOrchestrationClient starter,
ILogger log)
{
// Function input comes from the request content.
string instanceId = await starter.StartNewAsync("Function1", null);
log.LogInformation($"================================Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
}
我展示的是传入一个字符串类型的值,你可以替换成你想要的类型,类型兼容。
原答案:
activity 触发器一旦启动就无法停止。您可以选择将步骤分解为更多步骤。
看看offcial doc。 Activity 函数和子编排将 运行 完成,无论您是否已终止调用它们的编排实例。
我有一个 [DurableOrchestrationClient],它启动一个 [OrchestrationTrigger],它启动一个长 运行 [ActivityTrigger] 函数。
我知道如何使用 TerminateAsync() 来终止来自 运行 的 [OrchestrationTrigger]。
问题是当我终止 [OrchestrationTrigger] 函数时 [ActivityTrigger] 没有中止。 [ActivityTrigger] 保持 运行 直到完成。
当我调用 TerminateAsync() 时,我需要一种方法来中止长 运行 [ActivityTrigger]。
我的猜测是我可以将 CancellationToken 传递给 [ActivityTrigger] 函数,然后检查 cancellationToken.IsCancellationRequested 以中止。
但如何做到这一点?
这里是测试代码
[FunctionName("A_ProcessPayment")]
public static async Task<processTracker> A_ProcessPayment(
[ActivityTrigger] DurableActivityContext context,
TraceWriter log,
CancellationToken cancellationToken)
{
processTracker p = context.GetInput<processTracker>();
try
{
for (int i = 0; i < 5; i++){
if (cancellationToken.IsCancellationRequested) // This is always false!
{
break;
}
Trace.WriteLine("Long task loop: " + i);
await Task.Delay(10000);
}
}
catch (OperationCanceledException) {
log.Warning("C# HTTP trigger function canceled.");
return p;
}
Trace.WriteLine("Long task DONE");
return p;
}
更新:
您可以选择将令牌作为对象传递给 Activity 触发器,如下所示:
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
namespace OrchesterTrigger
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var outputs = new List<string>();
string mytoken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
outputs.Add(await context.CallActivityAsync<string>("Function1", mytoken));
return outputs;
}
[FunctionName("Function1")]
public static string SayHello([ActivityTrigger] string mytoken, ILogger log)
{
log.LogInformation($"Mytoken is {mytoken}.=======================================");
return $"Mytoken is {mytoken}!";
}
[FunctionName("Function1_HttpStart")]
public static async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
[OrchestrationClient]DurableOrchestrationClient starter,
ILogger log)
{
// Function input comes from the request content.
string instanceId = await starter.StartNewAsync("Function1", null);
log.LogInformation($"================================Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
}
我展示的是传入一个字符串类型的值,你可以替换成你想要的类型,类型兼容。
原答案:
activity 触发器一旦启动就无法停止。您可以选择将步骤分解为更多步骤。
看看offcial doc。 Activity 函数和子编排将 运行 完成,无论您是否已终止调用它们的编排实例。