2014/04/30

XPages の applicationScope 変数

ふと興味が湧いて、XPages のアプリケーションスコープ(applicationScope)変数について、こんなテストをしてみました。

おさらいとして、XPagesには
requestScope
viewScope
sessionScope
applicationScope
の4つのスコープ変数があります。

それぞれのライフサイクルを簡単に言うと、
requestScope はブラウザの更新ボタンあるいはXPageの完全更新(部分更新でなく)をすると使用できなくなります。このrequestScopeはページからページへパラメータを渡す際の元になる変数を格納したりします。

viewScopeはブラウザでページが再ロードされると使用できなくなります。
要は、requestScopeとviewScopeはひとつのページの中で、そのページ内のいくつかの場所で値を計算させたい場合に使用します。

sessionScope はユーザーセッションがタイムアウト(ある一定時間ブラウザでアプリを放ったらかしにして操作しない)になるまで、またはブラウザが再起動するまで有効です。典型的な使用例は、ユーザーに関する情報を格納する場合に使用されます。

最後に、applicationScopeはドミノサーバーが再スタートするまで有効、開発局面ではDomino Designer が再スタートするまで有効というのがその定義です。
今回興味を持ったのは、このapplicationScopeにファイルパスなどの固定情報を格納し、その値を使って他DBの参照をするといったケースで、このapplicationScopeが使えるかという疑問を持ったからです。
こんなコーディングを想定してみました。

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
 <xp:this.afterPageLoad><![CDATA[#{javascript:var now = new Date();
if (!requestScope.containsKey("requestVar")){
 requestScope.put("requestVar", "リクエストスコープ変数追加:" +now);
 }
if (!viewScope.containsKey("viewVar")){
 viewScope.put("viewVar", "ビュースコープ変数追加:"+now);
 }
if (!sessionScope.containsKey("sessionVar")){
 sessionScope.put("sessionVar", "セッションスコープ変数追加:"+now);
 }
if (!applicationScope.containsKey("applicationVar")){
 applicationScope.put("applicationVar", "アプリケーションスコープ変数追加:"+now);
 }
 
}]]></xp:this.afterPageLoad>
 <xp:table>
  <xp:tr>
   <xp:td>リクエストスコープ変数</xp:td>
   <xp:td>
    <xp:text escape="true" id="computedField1" value="#{javascript:requestScope.requestVar}"></xp:text>
   </xp:td>
  </xp:tr>
  <xp:tr>
   <xp:td>ビュースコープ変数</xp:td>
   <xp:td>
    <xp:text escape="true" id="computedField2" value="#{javascript:viewScope.viewVar}"></xp:text>
   </xp:td>
  </xp:tr>
  <xp:tr>
   <xp:td>セッションスコープ変数</xp:td>
   <xp:td>
    <xp:text escape="true" id="computedField3" value="#{javascript:sessionScope.sessionVar}"></xp:text>
   </xp:td>
  </xp:tr>
  <xp:tr>
   <xp:td>アプリケーションスコープ変数</xp:td>
   <xp:td>
    <xp:text escape="true" id="computedField4" value="#{javascript:applicationScope.applicationVar}"></xp:text>
   </xp:td>
  </xp:tr>
 </xp:table>
 <xp:button value="更新" id="button1" save="false" navigate="false">
  <xp:eventHandler event="onclick" submit="true" refreshMode="complete"></xp:eventHandler>
 </xp:button>
 <xp:button value="再ロード" id="button2">
  
 <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
  <xp:this.action><![CDATA[#{javascript:context.reloadPage()}]]></xp:this.action>
 </xp:eventHandler></xp:button>
</xp:view>

上記のコードの例では、applicationScopeのライフサイクルが本番環境ではドミノサーバーを再起動しないと使えないとなると、applictionScopeを使ってアプリケーションの参照パスを定義していた場合など、ドミノサーバーの変更なしでは以前のapplicationScopeの値を持ち続けるため、困ったことになりはしないかということです。

いちいち applicationScope に何を格納しているのか、コードレビューをしないといけないのはちょっと辛いです。

ドミノサーバー、またはDomino Designer を再起動する以外にapplicationScopeを一旦リセットする方法はないか、試しに設計の置換による変更を試してみました。
そうしたら、なんと予想どおり設計の置換でこのapplicationScopeをリセットすることがきました。
これで、本番稼働中にapplicationScopeの値をリセットしたい場合、設計の置換でサーバーを再起動することなくできそうです。今回はDomino Designer のみの環境で行いましたが、結局Domino Designer のHTTPを再起動するのとドミノサーバーのHTTPを再起動することは同じであろうということでサーバーでは試していません。もし、必要があればみなさんのほうでも確認してみてください。


2 件のコメント:

  1. コメントの投稿がうまくいかなかったみたいなので再度・・・
    「確認しておけ!」との命令?があったので、Domino サーバでのHTTP再起動での動作を確認してみました。
    その結果、applicationScopeの値は
    「tell http refresh」を実行しても、更新されませんでした。
    「tell http restart」を実行したら、更新されました。
    「tell http quit」と「load http」を実行したら、更新されました。

    という予想通りの結果でした。
    ご参考までに・・・

    返信削除