このブログは、旧・はてなダイアリー「檜山正幸のキマイラ飼育記 メモ編」(http://d.hatena.ne.jp/m-hiyama-memo/)のデータを移行・保存したものであり、今後(2019年1月以降)更新の予定はありません。

今後の更新は、新しいブログ http://m-hiyama-memo.hatenablog.com/ で行います。

CatyScriptとファシリティとエンティティ

Catyでは、コマンド/アクション(アクションはコマンドの特殊なもの)は薄緑の楕円で描くことにしている。単なる習慣だけど、習慣を守るとイチイチどうしようかと考えなくて済む。

CatyScriptは徹底的に図式的・絵的(pictorial/graphical/diagrammatic)な設計になっている。テキストで書くコマンドシェル言語だが、有向グラフによる可視化と対応するようになっている。スクリプトの基本要素であるコマンドノードは(今の習慣だと)薄緑の楕円なわけだ。

複数のコマンドノードのあいだを結ぶ矢印(ワイヤー、パイプ、ケーブル)には、まず、データフロー辺がある。CatyScriptでは、データフローと制御フローの区別がない。別な言い方をすると、制御は常にデータと共に流れるのだ。Catyでvoidデータが重要なのは、voidは情報は運ばないが制御を運ぶからだ。つまり、voidデータの受け渡しが、(実質的データ受け渡しを伴わない)制御の受け渡しとなる。

CatyScript/Catyスキーマの図示(可視化)では、ノードとなるコマンド、ワイヤー(のラベル)となる型以外に、次の要素が存在する。

  • クライアント状態(state)
  • ファシリティ(facility)

これらは、ロバストネス図では:

に対応する。もちろん、コマンドはコントロールオブジェクトに対応する。

最近になって、CatyScript/Catyスキーマでも、ファシリティの同義語(微妙に違うがほぼ同じ)として entity という言葉を使うことにした。ファシリティ/エンティティの図示の例は次。

ファイルシステム(Catyではmafsと呼ぶ)に対するファイル書き込みと同時に、KVSに管理用メタデータも書くとする。Data.putアクション(Webから呼び出せるコマンドがアクション)が、ファイルシステムとKVSの両方に書き込みを行う。Data.getアクションは、ファイルシステムからの読み出し。Data.indexアクションが、管理メタデータ一覧(インデックス)をKVSから読む。そういう状況を図示している。

コマンド/アクションとファシリティ/エンティティを結ぶ辺(矢印)は3種類。

  1. reads : データを読み出す。
  2. updates : データを書き込んで更新する。
  3. uses : 読み書きの両方を行う。

[追記]絵を描いたスクリプトを以下に貼る。[/追記]

// -*- coding: utf-8 -*-
/* ロバストネス図のバックエンド側のサンプル */
module g;

command action-node [string name] :: void -> gv:Node {
  gv:node 
    --fontsize=14.0
    --shape=ellipse
    --style=filled
    --color=black
    --fillcolor=darkseagreen2
  %1
};

command entity-node [string name] :: void -> gv:Node {
  gv:node 
    --fontsize=14.0
    --shape=Mcircle
    --style=filled
    --color=black
    --fillcolor=darkorange3
  %1
};

/* エッジの指定順序は、常に アクション エンティティ の順 */

command reads-edge [string act, string ent] :: void -> gv:Edge {
  gv:edge
    --dir=back
    --label=reads
  %1 %2
};

command updates-edge [string act, string ent] :: void -> gv:Edge {
  gv:edge
    --label=updates
  %1 %2
};

command uses-edge [string act, string ent] :: void -> gv:Edge {
  gv:edge
    --dir=both
    --label=uses
  %1 %2
};

command sample :: void -> gv:Digraph {
 [
   action-node act1,
   action-node act2,
   action-node act3,
   entity-node ent1,
   entity-node ent2,
   
   uses-edge act1 ent1,
   reads-edge act2 ent1,
   updates-edge act2 ent2,
   reads-edge act3 ent2,
 ] | gv:graph sample
};


command sample2 :: void -> gv:Digraph {
 [
   action-node Data.get,
   action-node Data.put,
   action-node Data.index,

   entity-node "mafs\npub",
   entity-node "kvs\nindex",
   
   reads-edge Data.get "mafs\npub",
   updates-edge Data.put "mafs\npub",
   updates-edge Data.put "kvs\nindex",
   reads-edge Data.index "kvs\nindex",
 ] | gv:graph sample2
};

// End of Module