[Tip] ガードチョイス アンチ・パターン「ツリーの変更停止」：更新され続けるサイトへの利用。。

## ガードチョイス（Guarded Choice）について

ガードチョイスって何かイメージしにくい名称ですが「指定した条件（`チョイス`）が満たされるまでは処理が先に進まないように監視（`ガード`）する機能」だから、`ガード チョイス` なのかなぁと思っています。

ガードの分類としては `ロケーションガード` と `タイムアウトガード` が存在し、それぞれ以下のような特徴を持ちます。

### ロケーションガード

`ファインダー` を指定条件に設定し、条件が満たされるまで監視を続けます。以下のガードが対象。

- アプリケーションが見つかった場合
- アプリケーションが見つからなかった場合
- ロケーションが見つかった場合
- ロケーションが見つからなかった場合
- 除去されたロケーション

### タイムアウトガード

`タイムアウト` を指定条件に設定し、時間が経過するまで監視を続けます。以下のガードが対象。

- 数秒が経過したとき
- ツリーの変更停止

## `ツリーの変更停止`について

タイムアウトガードとして定義されている `ツリーの変更停止` ですが、マニュアルでは以下の様に記載されています。

[マニュアルからの引用](https://docshield.kofax.com/RPA/ja_JA/11.3.0_5cdzhlgb3t/help/rpa_help/help_main/designstudio/c_dasguardedchoicestep.html)
> アプリケーション ツリーまたは Web ページ ツリーが変更されてからステップが実行されるまでに、指定された時間だけ待機するタイムアウト ガード。タイムアウトはミリ秒単位で指定されます。

話を単純化すると

- 新しい画面に遷移する時に、その画面の表示が完了しかつ操作可能な状態になったことを確認するために使用する。

ガードチョイスと言えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/c3f2cc7b-1d64-ded2-e654-01ffe10faade.png)
ロボットの操作対象は「:computer: `デバイス` > `アプリケーション`[^2] > `コンポーネント`[^3]」という階層になっていますが、`ツリーの変更停止` はアプリケーションレベルの状態をツリーの変更（≒画面の情報の生成）という観点でモニタリングしています。

:::note
タイムアウトガードは「時間の経過を監視する」ガードですが、ガードチョイスの処理開始と同時に時間経過を監視する `数秒が経過したとき`とは異なり、`ツリーの変更停止` では指定したアプリケーションレベルのファインダーがツリーの変更を完了した時点から時間経過を監視する点は注目に値します。
:::

## `ツリーの変更停止`への誤解

よく質問を受ける、または誤解を含むのが `「ミリ秒」の待ち時間って、適切ですか？` というもの。

**Q. なぜこのアクションだけ単位が ミリ秒 なんですか？**
**Q. 500ミリ秒っておかしくないですか？私は大体2000ミリ秒に書き換えてます。不具合でしょ。**

みたいなことも言われます。

ただ、回答としては「**安心してください。〇〇てます!**」

不具合じゃありませんし、2000秒に固定するも必要はありません。合ってます。

技術的な小難しい話になるから誰も話さないのかもしれませんが、現代のWebシステムがRPAにもたらす副作用なのでは？と個人的には思っています。


https://web-dev.translate.goog/rendering-on-the-web/?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=wapp

詳細は上のリンク記事を読んでいただければ詳しいと思いますが、`CSRにおけるイベントリスナーの有効化` 処理や、`SSRにおけるHydration`、その他 `Lazyloading含めた非同期処理` など。。複雑大規模になったWebフロントエンドの高速化やUXの向上のために使われている技術がブラウザ内部の動きを複雑化し、昔のWebページの様にHTMLファイルを読みこんだら完了。という状況も一部の業務Webシステムを除いては今や世界の片隅に追いやられてしまった印象です。[ここ](http://abehiroshi.la.coocan.jp/)👇とか。

http://abehiroshi.la.coocan.jp/

なんか理由はよくわからないけれど**画面の表示確認には `ツリーの変更停止` を使うのがいい**。ということで定常的に画面遷移時のガードとして使われるようですが、**アンチパターン** も存在します。

とはいえ、一般のBizRobo!ユーザが技術的にそれを見分けるのはしんどいと思います。なので、まずは考え方として「へぇ、こういう仕組みなんだ。」ということだけでも知っていただければ幸いです。

[^2]:画面とほぼ同意

[^3]:ボタンやテキストボックスなど、画面内の要素

## アンチパターン：更新し続けるページでの利用（無限ループへの道）

ある Webシステムの実際の画面です。このシステムはいわゆる Webストレージ と言われる分野のシステムで、社内ではファイルサーバとして利用しています。
![TreeDoesntStopChanging.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/f29267bd-fbfa-0fff-a4c3-470af79826a6.gif)
ご覧の通り、表示されている画面は変化していないのですが、画面下のWebページツリーが点滅して継続的に更新を繰り返しています。

この状態ではいつまでも `ツリーの変更停止` が成立せず無限ループに陥ってしまいます。[^4]

:::note
一方で、このようなケースで無視していい要素としては画面中断右側の瞬いているアイコンです。これは画面上ツリーを変更させている印にも見えますが、CSSなどにより単純に表示が変わっているだけの場合もあります。ややこしいですね。
:::

**勧められて `ツリーの変更停止` を使ってみたけど、いつまでたってもガードを抜けられなかった（無限ループ）**

という方は、もしかしたら本件のケースに遭遇してしまったのかもしれません。

実際 上記のシステムにおいては、**同一ページを複数人が同時に参照している間だけ発生する**挙動っぽい[^1]ので、ロボットを作っている段階では遭遇せず気づけないケースもあるでしょう。開発時には見逃してしまい、本番運用を開始してから現在化すると、これは非常にまずいですね。

[^1]: BOXでの例ですが、システムを自分で開発しているわけではないのであくまで「参考まで」の状況証拠です。

### 無限ループへの対応方法

状況に応じて以下のいずれかを採用します。

##### 1．`ツリーの変更停止` 内の「ミリ秒」設定を **「0」** にし、ツリー変更停止後のオーバーヘッドを考慮しない。

> クライアント側の処理として一定間隔（setIntervalなど）で更新を行っているWebシステムであれば、そのインターバルを待たずして処理を進めてしまいましょう。
ストリーミング通信をしていて常にツリーを変更している場合には停止のタイミングがつかめず改善しない。ということはあるかもしれませんが、結局はやってみてダメそうだったら 2．に移るという感じだと思います。

##### 2．`ツリーの変更停止` の利用を止めて `ロケーションが見つかった場合`（Location Found）による条件設定に変える。

> 当該アプリケーションで**何が表示されていればページの読込が完了したと見なせるか。** という人の判断の下、それを判定するための `ロケーションが見つかった場合` ガードを挿入します。
ログインが必要なシステムの場合には、画面右上のナビゲーションバーに表示されるログインユーザーのアイコンを目印に読込完了の判断をするケースが多いです。（その場合にはコンポーネント設定で**どの属性を条件に設定するか**が肝になります。）

[^4]:本アプリケーションの場合、ファイルを共有したり、複数の人が一つのフォルダやファイルにアクセスすることもよくあることです。そういった場合、ファイルが更新されればポップアップで「更新されたファイルがあります！」の様に表示されるのを見たことがある人も多いと思います。そういう類のWebシステムにおいては（同一URIに複数のユーザーが接続している場合は）常にサーバと通信をし、Webの表示を最新に保っておく必要があるため、このような挙動になると考えられます。

## まとめ

Don't think! Feel.

https://ameblo.jp/devikobayashi/entry-12369734335.html