• 検索結果がありません。

耐故障ソフトウェアの構造

ドキュメント内 JAIST Repository (ページ 66-70)

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).

これに対して、FTRecVFTRepVのプログラムは、次のような構造に変換される.

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).

ドキュメント内 JAIST Repository (ページ 66-70)