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

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

既存のAzure Functionsを Duable Functionに変更した(い)

ユーザー操作をトリガーとするユーザーに処理において処理を非同期にしてユーザーの待機時間する際に
Queue Triggerを採用しているがQueue Trigger内で複数の処理が重なると主にリトライポリシーで課題が発生していた

この問題を解決にするために、
Azure Functionsの拡張モデルであるDurable Functionを使用すると解決できそうという話

既存のアプリの課題

アプリ概要

既存のアプリはおおよそ、以下のようなシーケンスで処理を行っている

  • Process A

    ユーザーにリソースを付与される処理で、複数のリソースを割り当てないためにすでにリソースを持っている場合、この処理は失敗する

  • Process B

    外部APIを使用しており、時折処理が失敗することを許容しなければならない

  • Process C

    ユーザーに処理を通知する処理

  • Process D

    全ての処理の後処理でProcessCに関する後処理も含まれるためユーザー通知後に処理を行う

課題

この一連のAzure Functionsの処理は冒頭にも書いたが、処理失敗した際のリトライポリシーに問題を抱えており、
これは主にリトライがAzureFunctionsの処理単位でリトライされることに起因する

例えば、Process Aの処理に成功し、その後続処理で失敗した際のリトライでは Process Aで必ず失敗するのでリトライの意味がない

後続の処理が失敗した際、Process Aからリトライが行われるが
Process Aは一度だけ成功しなければならない特性上、確実に失敗する そのため、リトライで成功することはない

また、ユーザー通知後(Process C )の後の処理に失敗した場合では、仮にProcess Aで成功した際にはユーザーに2度通知することになる

外部APIに関わらず、ある程度の失敗とそのリトライを許容する場合、
複数処理があるようなAzure Functionsでは上記のような課題があった

これらの課題について、通常(?)のAzure Functionsでもある程度は対応できそうなするが、
頭からリトライせずにある一定の単位でリトライをしてほしいことの方が多い

Durable Functions への変更

Durable FunctionsはAzure Functionsを拡張したもので 処理の実行状態を一定のまとまりで保持することができるステーとフルな関数で オーケストラ関数の単位、アクティビティ関数で実行状態を監視できる 詳しくは以下参照

learn.microsoft.com

その性質上、リトライもこの単位で行うことができるので、 以前のAzure Functionsで行われる頭からのリトライを回避することができる

また、リトライポリシーについても
オーケストラ関数またはアクティビティ関数単位でカスタムすることができるので 柔軟なエラーハンドリングが実装できる見込みだ learn.microsoft.com

オーケストラまたはアクティビティ単位でリトライされる