/*
 * Paraselene
 * Copyright (c) 2009, 2010  Akira Terasaki
 * このファイルは同梱されているLicense.txtに定めた条件に同意できる場合にのみ
 * 利用可能です。
 */
package paraselene.supervisor;

import paraselene.*;

/**
 * デーモンチャネル。
 */
public interface DaemonChannel {
	/**
	 * 現在表示中で、バックグラウンド処理の管轄下にあるページ一覧を取得します。<br>
	 * タイミングによっては、バックグラウンド処理が目的とするページはユーザーに
	 * 閉じられているかもしれません。
	 * <br>このメソッドを呼び出すと、ユーザーリクエスト処理(または同一セッションを
	 * 管轄下に置く他のデーモン)に対し排他ロックをかけます。
	 * ページ操作を行う場合は、このメソッドから commitPage() の間で行って下さい。
	 * その間、ユーザーリクエスト処理はサスペンドしています。
	 * そのため、長時間ロックを占有しないで下さい。<br>
	 * 逆にユーザーリクエスト処理がロックを獲得していれば、その処理が終わるまで
	 * このメソッドからリターンしません。
	 * @return ポップアップ等を含めた表示ページ一覧。
	 */
	Page[] getPageForUpdate();

	/**
	 * 現在表示中で、バックグラウンド処理の管轄下にあるページ一覧を取得します。<br>
	 * 引数無しメソッドと異なり、指定された PageID のもののみ抽出して返します。
	 * @param id 取得ページ。
	 * @return ポップアップ等を含めた表示ページ一覧。
	 */
	Page[] getPageForUpdate( PageID ... id );

	/**
	 * getPageForUpdate と異なり、排他ロックの獲得ができなかった場合はメソッドから
	 * リターンします。<br>
	 * このメソッドが true を返す時、同時にページロックを獲得しています。
	 * 速やかに getPageForUpdate を行い後続処理を完了させて下さい。<br>
	 * false を返す時、ページロックは別のスレッドに取られています。
	 * @return true:ロック獲得、false:ロックできなかった。
	 */
	boolean tryLockPageForUpdate();

	/**
	 * ページの更新を終了し、排他ロックを解放します。
	 * この後、fw で指定した動作が実行されます。
	 * @param fw 動作指示。
	 */
	void commitPage( DaemonForward ... fw ) throws Exception;

	/**
	 * 他スレッドへ通信を行う。
	 * 他のバックグラウンド処理へ obj を post します。
	 * 指定スレッドが存在しない時、null を返します。
	 * @param name スレッド名。
	 * @param obj 送信インスタンス。
	 * @return post応答。
	 */
	Object postDaemon( String name, Object obj );

	/**
	 * 別のバックグラウンド処理を起動します。
	 * 呼び出される処理は、呼び出した処理の管理ページを引き継ぎます。
	 * 既に同名処理が実行されていれば、そのスレッドの管理ページに、
	 * 呼び出した処理の管理ページを追加します。
	 * @param name 処理名。
	 * null を指定すると無名処理になり、各アクセスメソッドが利用できません。
	 * @param daemon 処理インスタンス。
	 * 既に同名処理があれば、このインスタンスは破棄されます。
	 */
	void startDaemon( String name, Daemon daemon );

	/**
	 * 別のバックグラウンド処理からの管理ページ剥奪。
	 * このメソッドを呼び出したスレッドが管理しているページにあたるものを、
	 * 全てのバックグラウンド処理の管理下から外します。
	 */
	void depriveDaemonOfPage();

	/**
	 * 実行タイムアウトを延長します。<br>
	 * 通常、起動直後から30分経過するとスレッドはタイムアウトにより
	 * 強制停止させられ{@link KilledByTimeoutException}をスローします。<br>
	 * この時間延長を申請します。このメソッドコールから30分後が
	 * タイムアウト時間に変更されます。
	 */
	void delayTimeout();

	/**
	 * このスレッドが起動された時に付けられた処理名を返します。
	 * @return 処理名。
	 */
	String getDaemonName();
}

