なんかいろいろと書いてくブログ

関東のどこかで働く、一般人

Durable Functions 'Multithreaded execution was detected.'

Azure Functionsの拡張機能であるDurable Functionは状態をもつことができ、
非常に便利であるがその特性上いくつかコード制約がある

タイトルの'Multithreaded execution was detected.'もおそらく、
その規約にに引っかかかたものと思われる

エラーは、オーケストラ関数ないの繰り返処理で、
関数を直接awaitで待機しようとした際に発生した

[Singleton(Mode = SingletonMode.Function)]
[FunctionName(Orchestration_Funtion)]
public async Task Orchestration_Funtion(
[OrchestrationTrigger] IDurableOrchestrationContext context,
CancellationToken token,
ILogger log)
{
    var list = await context.CallActivityAsync("Activity_Trriger", null);
    foreach (var row in list)
    {
        // System.InvalidOperationException:
        // Multithreaded execution was detected
        await hogehoge() 
    }
    return;
}

持続的オーケストレーター コードの制約にもあるように、
オーケストラ関数内で、IDurableOrchestrationContext以外でawaitを使用できないので、
awaitで待機している関数hogehoge()をアクティブ関数に切り出す

[Singleton(Mode = SingletonMode.Function)]
[FunctionName(Orchestration_Funtion)]
public async Task Orchestration_Funtion(
[OrchestrationTrigger] IDurableOrchestrationContext context,
CancellationToken token,
ILogger log)
{
    var list = await context.CallActivityAsync<long>("Activity_Trriger", null);
    foreach (var row in list)
    {
        await context.CallActivityAsync("Activity_Hogehoge_Trriger", null); 
    }
    return;
}

[Singleton(Mode = SingletonMode.Function)]
[FunctionName("Activity_Hogehoge_Trriger")]
public async Task ActivityHogehogeTrriger(
[ActivityTrigger] OrchestrationAllTermCreateReportModel input)
{
    await hogehoge()
}

Multithreaded execution was detectedが発生した原因はおそらく、
コード制約にあるように、Durable Task Frameworkからつくられない(イベントソーシングとして記録されない)タスクの完了を待機できず、
foreach内で、複数同時に関数を実行した結果発生したものと思われる

参照

持続的オーケストレーター コードの制約 - Azure Functions | Microsoft Learn