Salesforceは非同期処理で強くなる？

Salesforce界隈が地元のエンジニア、[佐伯](https://x.com/yonyonsaeki) です。
Salesforceアドベントカレンダーの記事です。

https://qiita.com/advent-calendar/2024/salesforce



最終日25日を担当ということで、２本書きました。私は長文書くのが趣味なので許してください(アンカーだからとかじゃないので、来年以降真似しないでください)

QiitaにはSalesforceの技術っぽい話。noteはちょっとビジネス寄りの技術の話です。

note版はこちら
「早すぎる技術の進化が怖いだろうか？」

https://note.com/yonyon_saeki/n/n890ace977076


# Salesforceの非同期処理とはなんぞや？
同期処理、非同期処理ってエンジニア用語ですが、ビジネスユース出身の方からするとちょっと取っ付きづらいですよね。
最近はSlack等のチャットツールのおかげで非同期コミュニケーション、なんかもよく言うようになりました。

非同期コミュニケーションは、人と人が何か文字のやり取りをする時に、
話しかけるタイミングと、応答するタイミングが同時じゃなくていいものです。
対面で話しかけていて、５分無視されたら喧嘩になりますが、チャットは受け取り手のタイミングでメッセージを読んで打ち返せるわけです。

非同期処理も、人とシステムの対話において、指示と応答がその場で１セットで行われるのではなく、別々で行われます。

![CleanShot 2024-12-23 at 18.10.25@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391944/ebdbd3d5-c32e-de6e-7710-5593df8dc5d6.png)

# 非同期処理の例
内部的にはサーバーサイドの処理機構であるApexで処理されます。
該当するTrailheadを貼り付けておきます。
「非同期Apex」モジュール内、「非同期処理の基本」単元より

https://trailhead.salesforce.com/ja/content/learn/modules/asynchronous_apex/async_apex_introduction

![CleanShot 2024-12-23 at 18.11.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391944/c919e9fd-edcf-e2e3-cf5c-e3c93d6a3ce4.png)

Salesforceの"外部"のAPIを呼び出す処理、
データローダーのBulkAPIオプションで"大量"の処理、
特定の時間や特定の間隔で実行されるように"スケジューリング"する処理など。

外部、大量、スケジュール処理には非同期処理だ、ぐらいに思っておきましょう。

# 非同期処理のメリット
## ユーザの生産性向上
Trailheadだと長く書いてあるので端的に。
とあるCSVのリストをダウンロードしたいのに、エクスポートボタン押したあと白い画面のまま帰ってこない。
沢山待ったのに、なんかエラーが起きて処理が途中までで止まってしまった。

画面で、レコードの登録とか、xx処理とか、操作をしたら画面がクルクル回って帰ってこない。
しびれを切らして、一旦画面を更新したらまた最初から。

ユーザはイライラしますよね。待ってる時間があったら他の作業しておきたいですよね。
「別の作業しとくんで、終わった頃にまたこの画面戻ってきますね。」
という風にするには非同期処理です。

## ガバナ制限の緩和
非同期の場合、処理を捌いてくれるSalesforceサーバー側も
負荷や処理の立て込み具合をみて、いいタイミングで働けるわけなので制限が緩和されます。

ガバナ制限のヘルプを見ると、同期か非同期かで制限値が異なることがわかります。(画像は一例)

https://developer.salesforce.com/docs/atlas.ja-jp.252.0.apexcode.meta/apexcode/apex_gov_limits.htm

![CleanShot 2024-12-23 at 18.34.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391944/3d0b9ca2-1523-13ec-69ba-8ae47acb100f.png)

Salesforce環境を運用していると2-3年するうちにデータが増えてきて、
レコードを処理するフローが増えてきて、
フローがフローを呼ぶ処理とかがあって・・・
と、負債が貯まります。

おそらく、CPU Time Limit Exceededみたいなガバナエラーメールが飛んできます。
そんな時は、一旦の回避策として、特定の数珠つなぎになっている長い同期処理のフローを一部非同期化して回避する、といった作戦もとられたりします。

親ー子ー孫レコードがあって、親レコードを更新したらフローで子レコードを持ってきて、さらに孫レコードもってきて処理して、親レコードに戻ってくる・・・みたいなコストの高い処理でよくありがちです。
その場合、孫レコードの処理の結果に関わらず親レコードの処理を完了させていいんだったら、孫レコードの処理は、数分後に起動するスケジュールフローにしたり、毎時起動するスケジュールフローにする、といった具合です。

ただし、根本的には解決できてないのと、ミスるとデータの整合性が崩れてぐちゃぐちゃになるかもしれないので注意。後述する注意点や仕組みを踏まえて使いましょう。


# 非同期処理を処理するSalesforceサーバー側のイメージ
![CleanShot 2024-12-23 at 18.34.46@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391944/12e38f27-0f30-5bfe-0a8e-24911a8402e6.png)

あくまでイメージですが、こんな具合です。
Salesforceは多くの企業でサービスを共有して利用しています。
データはきちんと別々ですが処理の依頼を捌くコンピューティングリソースはみんなで共有しています。

それゆえに、サーバー側が混んでる時もあれば、そうでもない時もあります。
それだと、処理を沢山依頼するユーザ企業がいると偏りがでてしまうのでガバナ制限やエディション制限を設け、
無限ループのようなバグや品質の低いコードによる無駄な処理が出ないようにしたり、
上限を決めて公平性を維持しています。

# 非同期処理のよくある失敗・誤解
・処理の実行順序は依頼した順番通り担保される
　→どのキューに入るかで終了時間は変わるので、非同期処理を複数呼び出す時は注意。非同期処理AとBを呼び出す際に、A->Bの順で実行されないとエラーがおきる、不整合がおきるつくりになってないでしょうか？
 
・起動時にエラーが起きなかったので成功したのでらないか
　→処理が正常に受付されても、処理そのものが正常に完了するとは限らない
　→→監視画面を使ったり、ログを記録するようにしたり、リトライの仕組みをいれたりと考慮が必要

・特に重い処理回してないのにいつもより遅い気がする・・・
　→マルチテナントで自社以外の処理も動いてるので、全体の状況次第。落ち着いて。
 　→→ちなみにフローからメール送る場合など、システムの外に向かう動きは非同期になりがちです。レコードの受付フラグみたいなのがオンになったらメール通知飛ぶ、みたいなのも、基本すぐ飛ぶように見えますが内部的には一回キューに入ってたりするのでラグが出る時もあります。リアルタイムを期待しすぎないように。


# 非同期処理の状況を確認する
非同期の処理は依頼して応答までがワンセットで行われません。
なので、結果がどうなったか、今は依頼中で処理待ちなのかといった状況確認が必要になってきます。

設定画面に"ジョブ"と入力すると関連する設定がでてきます。画面古かったらごめんなさい。
![CleanShot 2024-12-23 at 18.40.20@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391944/ac0ebd7e-a2ee-9589-4428-cd7831e5d671.png)
![CleanShot 2024-12-23 at 18.41.14@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391944/8e55dcbe-7e7d-2f3a-8971-515e39cca6b9.png)

なんか実行されてないな、処理は完了したのか、それともなんかの理由で実行されていないのか・・・とか
実装間違えたせいでなんかジョブが溜まってしまってるっぽい・・・とか

何か問題があったり、作った非同期処理の動きを検証する際には利用しましょう。


#最後に
以上、非同期処理を使うとメリットがあったりするわけですが、

途中に書いたようにエラーを回避する目的で乱用しがちでもあるので、
今一度仕組みを踏まえて設計を見直すようにしましょう。

CPU　Time Limit Exceededのエラーがどうしても取れない場合は呼んでください。