2008-07-06

Jaxer におけるアプリケーション、ページ、セッションのスコープの考え方

Aptana Jaxer は、application、page、session、sessionPage という 4つのコンテナを持ち、そのコンテナごとにデータを保持できます。互いにコンテナは独立していて、データの相互関係はありません。ですので、アプリケーション、ページ、セッションを組み合わせたパターンのスコープがあると考えればよいです。

コンテナにデータを格納するコードは、次のとおりです。上から、アプリケーションごと、ページごと、アプリケーション単位のセッションごと、ページ単位のセッションごとを表しています。

<script type="text/javascript" runat="server">
//<![CDATA[
Jaxer.application.set('foo', 'bar1');
Jaxer.page.set('foo', 'bar2');
Jaxer.session.set('foo', 'bar3');
Jaxer.sessionPage.set('foo', 'bar4');
//]]>
</script>

コンテナからデータを参照するコードは、次のとおりです。コンテナの空間は独立していますので、コンテナをまたいだデータの関係はまったくありません。例えば、ページ単位のセッションでデータが見つからないとき、アプリケーション単位のセッションを参照するといったことはありません。

<script type="text/javascript" runat="server">
//<![CDATA[
Jaxer.application.get('foo');
Jaxer.page.get('foo');
Jaxer.session.get('foo');
Jaxer.sessionPage.get('foo');
//]]>
</script>

アプリケーションとページの単位は、configRoutes.js を使って定義できます。次のコードでは、Jaxer.Config.routes を使って、corgi アプリケーションと poodle アプリケーションを定義しています。

Jaxer.Config.routes = [
// corgi
function(uri) {
return uri.pathParts[0] == 'corgi'
? [uri.pathParts[0], uri.hostAndPort + uri.pathAndFile]
: null;
},
// poodle
function(uri) {
return uri.pathParts[0] == 'poodle'
? [uri.pathParts[0], uri.hostAndPort + uri.pathAndFile]
: null;
}
].concat(Jaxer.Config.routes);

Jaxer.Config.routes は配列で、その要素に Jaxer.Util.Url.parsedUrl が引数の Function を指定します。この Function は Jaxer がリクエストを受けたとき、配列の先頭から順番に実行され、その結果によって、アプリケーションとページの単位が決定します。

上の Jaxer.Config.routes は、http://[hostAndPort]/corgi/ 以下を corgi アプリケーション、http://[hostAndPort]/poodle/ 以下を poodle アプリケーションとして定義しています。それ以外のときは、Jaxer の初期値の定義を使うように、元の Jaxer.Config.routes を concat で結合しています。

Function は、引数の Jaxer.Util.Url.parsedUrl を使って、リクエストの内容を確認し、期待するリクエストのときは、2つの要素を持つ配列を返却します。1つ目の要素はアプリケーションの識別子です。Jaxer はこの識別子を使って、アプリケーションの単位を切り替えます。2つ目の要素はページの識別子です。Jaxer はこの識別子を使って、ページの単位を切り替えます。

アプリケーションとページの識別子は、文字列であれば何でもよいです(そうみえる)。アプリケーションの単位は決めることがあっても、ページの単位を決めることは、特別なときを除いてあまりないと思われます。ですので、ページの識別子は uri.hostAndPort + uri.pathAndFile といったように、ページの URL をそのまま使えば間違いはありません。

アプリケーションとページの識別子は、次のように key プロパティで確認できます。

<script type="text/javascript" runat="server">
//<![CDATA[
Jaxer.application.key;
Jaxer.page.key;
Jaxer.session.key;
Jaxer.sessionPage.key;
//]]>
</script>

また、コンテナのデータは、次のとおり、removeAll メソッドですべて削除できます。

<script type="text/javascript" runat="server">
//<![CDATA[
Jaxer.application.removeAll();
Jaxer.page.removeAll();
Jaxer.session.removeAll();
Jaxer.sessionPage.removeAll();
//]]>
</script>

私が調べた限りでは、Aptana Jaxer 0.9.7.2472 の時点では、セッションのタイムアウトをサポートしていないようです。レスポンスの Set-Cookie ヘッダをみると有効期限の指定がありませんので、ブラウザのセッション(ブラウザを閉じるまで)が有効期限になります。

また、removeAll メソッドを明示的に使わない限り、不要になったセッションのデータは、ローカルデータベースに残ったまま削除されません。データベースにはデータの格納日時と更新日時が含まれるので、削除しようと思えばできないことはありません。有効期限という考え方がない以上、削除する必要もないんですけどね。

データベースに残り続けて、データが蓄積していく状況は好ましくないと考えるので、本当にサポートしていないのか、もしくは何か手段があるのかは、今後の課題として調べていきます。

0 件のコメント: