【小ネタ】50以上の実行を同時に行いたい

# はじめに
Power Automate には複数の要素にそれぞれアクションを行う`Apply to each`（それぞれに適応する）というコントロール操作があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/40fc5fb8-52a7-867b-24a4-ae77e3041972.png)

この複数の要素に対するアクションで、待機を含むアクションや時間のかかるアクションがある場合、1つ目のループが終わらないと、次のループに入らないという問題があります。

例えば、このような、メンバー全員にアンケートを取るようなフローでは、１人の回答が滞ると、以降のメンバーには質問が届かないという問題があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/c305ff71-d9ca-c77f-f9f9-4c16571098d8.png)

これを避けるため、多重実行の設定、**コンカレンシー制御**という設定があります。
この設定をオンにすることで多重実行ができるので、複数のメンバーにも同時にアンケートを取ることができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/37e8b91f-ace2-e841-8f97-b5f3d7c2e94e.png)

ただし、この設定の最大値は50までですので、それより多い人数への多重実行はできません。

この記事はその制限を**無理やり超えよう**というものです。

# まずは普通にフローを作成
最初は普通にフローを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/e135a406-e8bd-b144-7f2d-8bded52b1642.png)

50以上の配列を作成するために、`range`関数で1~150の連番を作成しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/410ac159-46ee-94ab-2e3c-f6bfc5284116.png)

もちろんコンカレンシー制御はオンで50まで目いっぱい広げています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/672a6ac3-af67-0fb3-e232-db80f6d8df46.png)

# この状態で実行してみる
実行すると、待機時間を1時間持たせているため、次の実行はループには移りません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/15bb995c-a6fd-b5ea-f3cf-5aceb3753550.png)

結果をExcel のテーブルに記録しているのですが、確認すると50までしか
記録されていないのがわかります。
想定通りの結果ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/64e6111e-50d3-71a2-b4c3-fdc8fe2dfc8c.png)

ちなみに、テーブルの番号がバラバラなのはコンカレンシー制御が実行順序を保証しないからです。
順序が必要な場合には、コンカレンシー制御の使用は難しいので注意です。

# 配列を小分けにする
50までしか同時に実行できないのであれば、50ずつに分割してあげましょう。
ということで、作成アクションに`chunk`関数で、配列を分割する処理を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/1fe1a82e-fbb6-175a-8cd6-5b6dc4f2fafe.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/0fddd813-8cc3-a366-afee-335900ab8e20.png)

https://learn.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#chunk

この関数は、配列に使用した場合、指定した要素数で分割することができます。


実行すると、このように指定した数、50ずつの配列に分割されることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/166c41fd-c82a-5b10-155d-5acd2419e33f.png)


# さらにApply to each で囲む(ダメパターン)
さて、分割できたら多重の多重実行になるように、もとからあったApply to each をさらにApply to eachで囲んであげます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/751e46ba-fc8e-f272-fd8e-461d983c6729.png)

どちらのApply to each も並列処理の時数を50に設定しています。
これで50×50=2500の並列処理が叶うはず…。

実行してみた結果がこちら！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/0d652290-9b7c-cc2c-718b-5a062c0ba395.png)

・・・あれ？
どうやら入れ子になったApply to each では、外側のループでしか並列処理が実行されないようです。

# 子フローに分ける
入れ子ではできなかったので、子フローに分けて疑似的に入れ後を解消します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/885c0e3a-e3dd-49fb-19b0-2f360215fada.png)

子フローのInputには配列やオブジェクトの型指定がなさそうでしたので、`string`関数でJOSN文字列に変換して子フローに送ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/54f05080-ada7-fe50-2f96-ffc1a1b1ed48.png)

子フロー側では、受け取ったJSON文字列を`json`関数で配列に戻してあげます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/3766983b-c914-b242-418f-73a43bda1157.png)

# 動作確認
実行すると、瞬時に150の項目が入力されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/45f26092-bb7b-df82-44b4-af1173f1e792.png)

親フローでは3件(150÷50=3)の子フローが同時に実行されており。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/cebbcee9-8725-0b37-9549-341e9e7f6620.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/05b37e98-c87c-8084-04e7-4e40f6de9574.png)

子フローは、各50件の実行が並列起動して待機状態になっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/b8f1b290-fc8c-54a9-3dc3-a0de744d19f1.png)
これで応答を待つ50件以上の実行を同時に行うことができそうです。

# おわりに
Apply to each の入れ子で並列処理ができないのは意外でした。

同時実行数をあまりにも多くすると、接続先のサービスに対して大きな負荷をかけることになります。
受け入れ先APIの仕様で短期間に受け付ける要求数を制限されることはよくありますので、使用するサービスの仕様とよく相談の上ご使用ください。