失敗から学ぼうシリーズ:つまらない失敗体験でも、記録に残しておけば教訓として残り、つぎに同じ失敗をしないだろう。いやもし同じ失敗をしても、記録を読めばすぐに解決できるだろう。という企画です。
--
WebObjectsでログイン・ログアウトを行うアプリケーションを開発中です。ログイン・ログアウトをログ情報として記録して、後に統計や不具合対応などに利用しようとしてデータベースに保存することにしました。
ただ、Webアプリケーションの特徴としてログインユーザーの情報をセッション情報として保持しますが、長時間アクセスがなかった場合に、自動的にセッションを終了させてしまう必要があります。そしてWebObjectsではこの処理は自動的に実行されます(セッションタイムアウト)。
さて、セッションタイムアウトで終了した時には、ログアウト処理は明示的に呼び出されないため、実行されません。そこでセッションタイムアウト時に呼ばれる処理のなかでログアウトを記録する処理を実行しないといけません。
これらを以下のように実装しました。ファイルSession.java中。
protected boolean isLogedOut = false;
public void logout() {
EEUserLog.createLogForLogout( loginUser );
isLogedOut = true;
}
public void terminate(){
if ( isLogedOut ) {
} else {
EEUserLog.createLogForTimeout( loginUser );
}
}
logout()は、明示的にログアウトしたときに、WOComponentから呼び出します。terminate()はセッションを終了する時に呼び出します。明示的に終了する時には以下のように呼び出します。
public class LogoutPage extends WOComponent {
public LogoutPage(WOContext context) {
super(context);
}
public void sleep() {
((Session)session()).logout();
session().terminate();
}
}
terminate()はまた、セッションタイムアウト時には自動的に呼び出されます。これで完璧なはずでした。
が、問題発生。まず、このアプリケーションを運用環境で実行時にスケジュールの設定をしました。これは、深夜など普段人が使っていない時間帯に自動的にアプリケーション再起動を行う設定です。ところが、設置2日目にログインしようとするとインスタンスが見つからないエラーです。ですが、lsofなどで見るとアプリケーションのプロセスは存在しているみたいです。killで殺して再起動すると使えます。翌日も同じ。試しにスケジュールを切ると一応何日も使えます。その状態でJavaMonitorで見ると、なんとセッション数が異常に多い。
セッションが終わっていないみたいです。そうです、上記コードはこう書かないといけなかったんです。
public void terminate(){
if ( isLogedOut ) {
} else {
EEUserLog.createLogForTimeout( loginUser );
}
super.terminate();
}
フレームワークのメソッドをオーバーライドしたのに親クラスのメソッドを呼び出していないので本来必要な処理が呼び出されていなかったんです。
間抜けなぽかミスですが、1行追加で無事終了。
posted by 永遠製作所 at 19:05|
Comment(0)
|
TrackBack(0)
|
WebObjects
|

|