DCPDCP DCP
8.1 耐故障ソフトウェアの構造
ユーザプログラムには、
1. 耐故障実行させる述語、
2. その述語内で負荷分散させるゴール
が指定されているものとする.耐故障実行させる述語は、プラグマfault_tolerant が付 加される.負荷分散させるゴールは、プラグマnode が付加される.負荷分散プラグマは、
KL1オリジナルのプラグマnode(N)(Nは論理ノードアドレス)でも良いが、耐故障実行 させる際に実際に転送されるノードは、指定のものとは異る.
変換の概要は、図8.1のようになる.すなわちユーザ指定の述語methodに対して、耐故 障ソフトウェアは次のような操作に置き換わる.
...,
method @ fault_tolerant, ...
Original User Program
method definition
Fault Tolerant Program ...
method, ...
fault tolerant method definition method
fork_watchdogs,
replicate(method’,One,Another), do_on_primary(One),
do_on_backup(Another).
Replay Version of method Record Version of method
external call method definition
Library
図8.1: Convertingoriginal program
1. fork_watchdog: 監視プロセスのネットワークを構成させる.
2. replicate: ゴールの複製を作る.
3. do_on_primary: Primary SiteGroupでのゴール実行を指定する.ゴールは、Record
Versionで実行される.
4. do_on_backup: Backup Site Groupでのゴール実行を指定する.ゴールは、Replay
Versionで実行される.
また、ライブラリからユーザプログラムを呼び出す必要から、外部呼出し述語を定義する.
変換後のプログラムは、ライブラリとして用意してある監視プロセス(watchdog)、複製
プロセス(replicate)とともにリンクして、実行形式が得られる.
8.1.1 FTRecV/FTRepV
プログラムの構造
KL1プログラムにおけるプロセスの処理は、通例次のような列になる.
1. 入力処理: 入力値の待ち合わせを含む.
2. 条件分岐: 成立条件に応じて、いずれかの部分処理に分岐する.
3. 部分処理: 出力、別プロセスの生成を含む.
4. 繰り返し: 1へ戻る.並列論理プログラムでは、再帰呼出しに相当する.
例)入力[In|In1]を待ち、Inの値を条件として、いずれかの部分処理(クロー
ズ)に分岐する.各クローズのボディのユニフィケーションは、引数Outへの 出力となっている.
% 非決定的述語
nondet([In|In1],Out) :- In =< 0 |
Out = [-1|Out1], nondet(In1,Out1).
nondet([In|In1],Out) :- In >= 0 |
Out = [1|Out1], nondet(In1,Out1).
% 決定的述語
det([In|In1],Out) :- In < 0 |
Out = [-1|Out1], det(In1,Out1).
det([In|In1],Out) :- In >= 0 |
Out = [1|Out1], det(In1,Out1).
これに対して、FTRecV、FTRepVのプログラムは、次のような構造に変換される.
FTRecV :
1. 入力処理: 非決定的実行に対する、返信の待ち合わせが追加される.
2. 条件分岐
3. 部分処理: 条件分岐が非決定的であれば、分岐情報をログとして対応するプロ セスへ送る.
4. 繰り返し
例)ヘッドack(Log)で、返信の待ち合わせを行い、ボディのLogへのユニ フィケーションがログの送信にあたる.プロセス内の出力(ユニフィケー ション)は、ログに対する返信が返った後でのみ実行される.出力を含む 決定的述語は、最初に先のログに対する返信の待ち合わせをする以外は、
オリジナルの述語に同じ.
nondet_record([In|In1],Out,ack(Log)) :- In =< 0 |
Log=c1(Log1),
(wait(Log1) -> Out = [-1|Out1]),
nondet_record(In1,Out1,Log1).
nondet_record([In|In1],Out,ack(Log)) :- In >= 0 |
Log=c2(Log1),
(wait(Log1) -> Out = [1|Out1]),
nondet_record(In1,Out1,Log1).
det_record(In,Out,Log) :- wait(Log) | det(In,Out).
FTRepV :
1. 割り込み処理: 監視プロセスからの割り込みがあれば、FTRecV実行に切り替 わる.
2. 入力処理: 非決定的実行に対する、ログの待ち合わせが追加される.
3. 条件分岐
4. 部分処理: ログに対する返信を送る.
5. 繰り返し
例)ログが送られてくる間は、処理本体nondet_replay_1を呼び出す.そ うでなければ割り込みチェックを行い、割り込みがあればFTRecV実行へ 切り替わる.処理本体では、ガードでログの待ち合わせが含まれる.決定
(wait(Log) -> nondet_replay_1(In,Out,Log,Control) ;
alternatively;
'割り込みチェック'(Control) -> nondet_record(In,Out,NewLog)).
nondet_replay_1([In|In1],Out,Log,Control)
:-Log = c1(Ack), In =< 0 | Ack = ack(Log1),
Out = [-1|Out1], nondet_replay(In1,Out1,Log1,Control).
nondet_replay_1([In|In1],Out,Log,Control)
:-Log = c2(Ack), In >= 0 | Ack = ack(Log1),
Out = [1|Out1], nondet_replay(In1,Out1,Log1,Control).
det_replay(In,Out) :- det(In,Out).