メインコンテンツまでスキップ

コンテンツ更新後のトリガが二重に呼ばれるのはなぜですか?

トリガの処理内に自身のトリガの実行条件を満たす処理を書いた場合、つまり、トリガのループを作る処理を書いた場合にトリガが2回呼ばれることがあります。
以下に無限ループに対するKurocoの制約と、トリガが2回呼ばれる理由について説明します。

無限ループについて

「Api::request_api のエンドポイントに設定したカスタム処理内で自身のエンドポイントを呼ぶ」、「後処理に設定したカスタム処理で自身のエンドポイントを呼ぶ」など、誤った実装をしてしまった場合、関連するアクションが連続的に実行され、プログラムが終了しない状態となります。
無限ループは、サーバーの負荷を高め、リソースの浪費を引き起こすため、重大な問題です。

APIに設定されたループに関する制約

Kurocoでは無限ループへの対策としてAPIに以下の制限を設けています。

自身のエンドポイントへのリクエストを禁止

カスタム処理では、自身を呼び出したエンドポイントに対してリクエストを送ることができません。
この制約により、以下の実装をした場合は、エンドポイントへのリクエストがキャンセルされ、処理が終了します。

  • Api::request_api/Api::request_api_post のエンドポイントに設定したカスタム処理内で自身のエンドポイントを呼ぶ
  • 前処理/後処理に設定したカスタム処理で自身のエンドポイントを呼ぶ

など。

多段APIの禁止

KurocoではAPIを多段で呼び出すことを禁止されています。例えば {api_internal} プラグインからAPIを呼び出し、そのAPI実行時さらに {api_internal} が実行されるとエラーとなります。

トリガをベースにした処理ループ

ループ終了までのプロセス

トリガをベースにしたループを作成した場合、例えばコンテンツ編集後のトリガ内でコンテンツ編集を行うAPIを呼び出した場合、1回目のトリガにおけるAPI呼び出しは管理画面コンテンツ編集画面が呼び出し元となるため、上記の自身のエンドポイントへのリクエストを禁止による制約は受けず、APIによるコンテンツ編集が行われ2回目のトリガが実行されます。
2回目のトリガでのAPI呼び出しは自身のエンドポイントが呼び出し元になるため、APIリクエストがキャンセルされてループが終了します。

コンテンツ更新(管理画面)

トリガ実行(1回目)
コンテンツ更新のAPIリクエスト(1回目)

コンテンツ更新(API)

トリガ実行(2回目)
コンテンツ更新のAPIリクエストは制約によりキャンセル

処理終了

トリガのループを1回で終了する記述

コンテンツ更新後のトリガを利用して、同じコンテンツ定義のコンテンツを更新する際、トリガの実行を1回で終了させたい場合は以下のコードをカスタム処理の先頭に記述してください。

{if $smarty.server.HTTP_RCMS_X_API_REQUEST_CNT > 0}
{return}
{/if}

サポート

お探しのページは見つかりましたか?解決しない場合は、問い合わせフォームからお問い合わせいただくか、Slackコミュニティにご参加ください。