我目前正在开发一个持久功能来处理大文件上传,并且在尝试本地测试活动超时时遇到一些问题。
简而言之,我尝试测试的场景如下:orchestrator 将处理上传所需的信息传递给某个活动 (
ResumeUpload
),并且该活动的 CallActivityAsync
任务是否因以下原因导致 TaskFailedException
失败?超时,然后我就会知道上传尚未完成,我应该再次调用它来恢复上传。
为了实现此目的,我在我的
"functionTimeout": "00:01:00"
中设置了 host.json
,并使用 ResumeUpload
将 Task.Delay()
更改为无限期等待。
在发生超时之前,这一切正常,此时我希望 VS 在协调器捕获 TaskFailedException
的断点处停止;相反,dotnet.exe
会死掉并且调试会话结束。
编排器和活动(简化):
[Function(nameof(RunOrchestrator))]
public static async Task RunOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
{
var logger = context.CreateReplaySafeLogger(context.Name);
var uploadRequest = context.GetInput<UploadRequest>();
try
{
await context.CallActivityAsync(nameof(ResumeUpload), uploadRequest);
}
catch (TaskFailedException ex)
{
// This is never reached!
logger.LogError(ex, "inspect task failure exception");
}
}
[Function(nameof(ResumeUpload))]
public static async Task ResumeUpload([ActivityTrigger] UploadRequest uploadRequest, FunctionContext context)
{
// Force this activity to time out
await Task.Delay(TimeSpan.FromHours(1));
}
发生超时时,我在运行项目时 VS 生成的终端中看到一条消息,到目前为止一切顺利:
[2024-11-06T17:10:06.427Z] Microsoft.Azure.WebJobs.Host: Timeout value of 00:01:00 was exceeded by function: Functions.ResumeUpload.
[2024-11-06T17:10:08.451Z] A function timeout has occurred. Restarting worker process executing invocationId '9d808fd3-6274-4211-9dcf-d514e8fe3ec2'.
然而,该进程随后立即终止,并且我被转回 VS,而没有到达我在协调器的
catch
语句中放置的断点。如果我尝试捕获通用 Exception
而不是 TaskFailedException
,情况也是如此。
我已经在 Google 上搜索了几个小时,但没有遇到任何人报告此问题,并且在我的搜索中,我遇到了几个示例,这些示例表明我正在尝试做的事情应该是可能的,例如:
我对 Azure Functions 非常陌生,所以我可能会遗漏一些明显的东西,感谢您能想到的任何帮助或提示!预先感谢。
编辑:
我将该函数部署到 Azure,当活动超时时,编排器确实捕获了
TaskFailedException
,因此这看起来像是我的机器/VS/Azure 模拟器的问题。
我可以通过用 try-catch 块封装活动函数来运行您的代码,并且能够命中 Orchestrator 函数的 catch 块中的异常。
修改示例代码:
public static class Function1
{
[Function(nameof(Function1))]
public static async Task RunOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
{
var logger = context.CreateReplaySafeLogger(context.Name);
var uploadRequest = context.GetInput<UploadRequest>();
try
{
await context.CallActivityAsync(nameof(ResumeUpload), uploadRequest);
}
catch (TaskFailedException ex)
{
logger.LogError(ex, "inspect task failure exception");
}
}
[Function(nameof(ResumeUpload))]
public static async Task ResumeUpload([ActivityTrigger] UploadRequest uploadRequest, FunctionContext context,ILogger logger)
{
try
{
await Task.Delay(TimeSpan.FromHours(1));
}
catch (TaskFailedException ex)
{
logger.LogError("inspect activity task failure exceptions");
}
}
[Function("Function1_HttpStart")]
public static async Task<HttpResponseData> UploadRequest(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
[DurableClient] DurableTaskClient client,
FunctionContext executionContext)
{
ILogger logger = executionContext.GetLogger("Function1_HttpStart");
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
nameof(Function1));
logger.LogInformation("Started orchestration with ID = '{instanceId}'.", instanceId);
return await client.CreateCheckStatusResponseAsync(req, instanceId);
}
能够在异常catch块处命断点。
输出:
Functions:
Function1_HttpStart: [GET,POST] http://localhost:7070/api/Function1_HttpStart
Function1: orchestrationTrigger
ResumeUpload: activityTrigger
For detailed output, run func with --verbose flag.
[2024-11-07T07:17:44.908Z] Executing 'Functions.Function1' (Reason='(null)', Id=53e3689e-e412-4ac5-ac5a-2f48651e7c4a)
[2024-11-07T07:17:49.162Z] Host lock lease acquired by instance ID '000000000000000000000000F72731CC'.
[2024-11-07T07:18:05.470Z] inspect task failure exception
[2024-11-07T07:18:05.471Z] Result: inspect task failure exception
Exception: Microsoft.DurableTask.TaskFailedException: Task 'ResumeUpload' (#0) failed with an unhandled exception: Exception while executing function: Functions.ResumeUpload
[2024-11-07T07:18:05.473Z] ---> DurableTask.Core.Exceptions.TaskFailedException: Exception of type 'DurableTask.Core.Exceptions.TaskFailedException' was thrown.
[2024-11-07T07:18:05.475Z] at DurableTask.Core.TaskOrchestrationContext.ScheduleTaskInternal(String name, String version, String taskList, Type resultType, Object[] parameters) in /_/src/DurableTask.Core/TaskOrchestrationContext.cs:line 121
[2024-11-07T07:18:05.477Z] at DurableTask.Core.TaskOrchestrationContext.ScheduleTaskToWorker[TResult](String name, String version, String taskList, Object[] parameters) in /_/src/DurableTask.Core/TaskOrchestrationContext.cs:line 92
[2024-11-07T07:18:05.478Z] at DurableTask.Core.TaskOrchestrationContext.ScheduleTask[TResult](String name, String version, Object[] parameters) in /_/src/DurableTask.Core/TaskOrchestrationContext.cs:line 84
[2024-11-07T07:18:05.480Z] at Microsoft.DurableTask.Worker.Shims.TaskOrchestrationContextWrapper.CallActivityAsync[T](TaskName name, Object input, TaskOptions options)
[2024-11-07T07:18:05.481Z] --- End of inner exception stack trace ---
[2024-11-07T07:18:05.483Z] at Microsoft.DurableTask.Worker.Shims.TaskOrchestrationContextWrapper.CallActivityAsync[T](TaskName name, Object input, TaskOptions options)
[2024-11-07T07:18:05.484Z] at FunctionApp1.Function1.RunOrchestrator(TaskOrchestrationContext context) in C:\Users\uname\Source\Repos\FunctionApp1\FunctionApp1\Function1.cs:line 19
Stack: at Microsoft.DurableTask.Worker.Shims.TaskOrchestrationContextWrapper.CallActivityAsync[T](TaskName name, Object input, TaskOptions options)
[2024-11-07T07:18:05.488Z] at FunctionApp1.Function1.RunOrchestrator(TaskOrchestrationContext context) in C:\Users\uname\Source\Repos\FunctionApp1\FunctionApp1\Function1.cs:line 19.
[2024-11-07T07:18:11.197Z] Executing 'Functions.Function1' (Reason='(null)', Id=3797fe6c-3f4c-4561-b9e5-5093c44bea9d)
[2024-11-07T07:18:24.414Z] inspect task failure exception
[2024-11-07T07:18:24.416Z] Result: inspect task failure exception
Exception: Microsoft.DurableTask.TaskFailedException: Task 'ResumeUpload' (#0) failed with an unhandled exception: Exception while executing function: Functions.ResumeUpload
[2024-11-07T07:18:24.419Z] ---> DurableTask.Core.Exceptions.TaskFailedException: Exception of type 'DurableTask.Core.Exceptions.TaskFailedException' was thrown.
[2024-11-07T07:18:24.421Z] at DurableTask.Core.TaskOrchestrationContext.ScheduleTaskInternal(String name, String version, String taskList, Type resultType, Object[] parameters) in /_/src/DurableTask.Core/TaskOrchestrationContext.cs:line 121
[2024-11-07T07:18:24.423Z] at DurableTask.Core.TaskOrchestrationContext.ScheduleTaskToWorker[TResult](String name, String version, String taskList, Object[] parameters) in /_/src/DurableTask.Core/TaskOrchestrationContext.cs:line 92
[2024-11-07T07:18:24.425Z] at DurableTask.Core.TaskOrchestrationContext.ScheduleTask[TResult](String name, String version, Object[] parameters) in /_/src/DurableTask.Core/TaskOrchestrationContext.cs:line 84
[2024-11-07T07:18:24.427Z] at Microsoft.DurableTask.Worker.Shims.TaskOrchestrationContextWrapper.CallActivityAsync[T](TaskName name, Object input, TaskOptions options)
[2024-11-07T07:18:24.429Z] --- End of inner exception stack trace ---
[2024-11-07T07:18:24.432Z] at Microsoft.DurableTask.Worker.Shims.TaskOrchestrationContextWrapper.CallActivityAsync[T](TaskName name, Object input, TaskOptions options)
[2024-11-07T07:18:24.434Z] at FunctionApp1.Function1.RunOrchestrator(TaskOrchestrationContext context) in C:\Users\uname\Source\Repos\FunctionApp1\FunctionApp1\Function1.cs:line 19
Stack: at Microsoft.DurableTask.Worker.Shims.TaskOrchestrationContextWrapper.CallActivityAsync[T](TaskName name, Object input, TaskOptions options)
[2024-11-07T07:18:24.436Z] at FunctionApp1.Function1.RunOrchestrator(TaskOrchestrationContext context) in C:\Users\uname\Source\Repos\FunctionApp1\FunctionApp1\Function1.cs:line 19.
[2024-11-07T07:18:44.910Z] Timeout value of 00:01:00 exceeded by function 'Functions.Function1' (Id: '53e3689e-e412-4ac5-ac5a-2f48651e7c4a'). Initiating cancellation.
[2024-11-07T07:18:44.952Z] Executed 'Functions.Function1' (Failed, Id=53e3689e-e412-4ac5-ac5a-2f48651e7c4a, Duration=60078ms)
[2024-11-07T07:18:44.953Z] Microsoft.Azure.WebJobs.Host: Timeout value of 00:01:00 was exceeded by function: Functions.Function1.
[2024-11-07T07:18:46.988Z] A function timeout has occurred. Restarting worker process executing invocationId '53e3689e-e412-4ac5-ac5a-2f48651e7c4a'.
[2024-11-07T07:18:47.270Z] Azure Functions .NET Worker (PID: 3888) initialized in debug mode. Waiting for debugger to attach...
[2024-11-07T07:18:50.624Z] Executed 'Functions.Function1' (Succeeded, Id=3797fe6c-3f4c-4561-b9e5-5093c44bea9d, Duration=39430ms)