プロセスを組み合わせて処理を実施する場合、プロセスは互いに連携をとる必要がある。この要求に応える仕組みとして、UNIX系OSではプロセス間通信と呼ばれる機能が提供されている。
たとえば次のようなプロセス間通信がある。
ユニケージ開発手法の作法として、ここでひとつ注意する必要がある。こうしたプロセス間通信の機能は、どれも「通信」をする「機能」であるということだ。通信の機能であって、これら機能が連携そのものを定めるものではない。「通信」と「連携」は区別する必要がある。
ユニケージ開発手法では「相手の状態や振る舞いは参考にはするが、自分がとるべき行動は自分で決める」という連帯の取り方を基本としている。自律して振る舞うということだ。ユニケージ開発手法においてプロセス間通信は、あくまでもこうした「連携の作法」を実現するための機能でしかない。
自律的に振る舞うよう設計されたシステムについて、サラダの調理という仕事を例にとり、これをシステム的に観察して説明したい(この例はシステム設計において本質的なもので、システムを設計する際の考え方としても有益なので、今回の話に限らず参考にしてみてほしい)。
まず食材がある。野菜・卵・調味料等、これらが入力データということになる。完成品はサラダだ。最初の食材を交ぜて作るわけだが、これらの食材は別々の加工を受けてから混ぜられる。野菜は洗われた後、食べやすい大きさに切られる。一方、調味料は直接、最終工程「和える」に使われる。卵はゆで卵作りに回される分とマヨネーズ作りに回される分がある。このように、中間生成物がいくつも生じる。
ここで、中間生成物や完成品などの成果物をつくるそれぞれの作業担当者をプロセスとみなす。どのプロセスも自律して振る舞う。必要な食材や中間生成物、つまり材料がそろうのを待ってから、自分の作るべき成果物の作成に取りかかる。材料を提供することになる他のプロセスと蜜に意思疎通をする必要はない。
自律性の高い設計にしておけば、柔軟性が増す。改良や障害対応も容易に行える。たとえば、野菜から何から全部投入するだけで済むサラダ製造機を開発した場合、最初は便利かもしれないが、今の味に飽きてレシピを変えたくなった時、製造機が対応している範囲でしか変えられない。また機械が故障したら、蓋を開けて原因箇所を特定して修理するか、丸ごと買い換える、または新しく開発する必要がある。
自律性を意識したシステム設計をする上で、ユニケージエンジニアが実際に用いている作法を説明する。リスト1~4がそれだ。これら4つのリストは同時に起動し、個別のプロセスとして動くものと考えてほしい。どれも、何らかの入力ファイルを元に、何らかの出力ファイルを生成している。
#!/bin/sh #====================================================================== #リスト1.TENPONAME_MAKER.sh #(店情報マスターから、①店舗ID-店舗名テーブルを作成) #====================================================================== # 1)店情報マスターから店IDと店舗名のデータを抽出 cat IN-DIR/NAMEMASTER | awk '$1=="TENNAME"' | self 2 3 | # 1:店舗コード 2:店舗名 LANG=C sort > TMP-DIR/TENPONAME # 2)完成の証として作ったデータと同じ場所に # "<ファイル名>.SEM"という名のダミーを置く touch TMP-DIR/TENPONAME.SEM
#!/bin/sh #====================================================================== #リスト2.URE_MAKER.sh #(売上データから、②店舗毎販売実績テーブル の作成) #====================================================================== # 1)売上データから店舗毎の販売数・額テーブルを作成 cat in-dir/URE | self 2 11 12 | # 1:店舗コード 2:販売数 3:販売額 LANC=C sort | sm2 1 1 2 3 > TMP-DIR/URE # 2)完成の証として作ったデータと同じ場所に # "<ファイル名>.SEM"という名のダミーを置く touch TMP-DIR/URE.SEM
#!/bin/sh #====================================================================== #リスト3.TENPONAME-CSV_OUTPUT.sh #(前出①から、③CSV版店舗ID-店舗名テーブルの作成) #====================================================================== # 1)店舗ID-店舗名テーブルファイル(TENPONAME)の # 完成を待つ(1分毎に確認) today=$(date +%Y%m%d) while sleep 60; do [ -e OUT-DIR/TENPONAME.SEM ] && break [ "$today"235959 -lt $(date +%Y%m%d%H%M%S) ] \ && exit 1 done # 2)店舗ID-店舗名データファイルを # Shift-JIS形式のCSVファイルに変換 cat TMP-DIR/TENPONAME | tr " " "," | nkf -sLwx > OUT-DIR/TENPONAME.CSV # 1:店舗コード 2:店舗名
#!/bin/sh #====================================================================== #リスト4.TENPOURECSV-OUTPUT.sh #(前出①,②から、④CSV版店舗名付店舗毎販売実績テーブルの作成) #====================================================================== # 1)下記の2つのファイルの完成を待つ(1分毎に確認) # ・店舗ID-店舗名テーブルファイル(TENPONAME) # ・店舗毎販売実績テーブル(URE) today=$(date +%Y%m%d) while sleep 60; do [ -e TMP-DIR/URE.SEM -a \ -e TMP-DIR/TENPONAME.SEM ] && break [ "$today"235959 -lt $(date +%Y%m%d%H%M%S) ] \ && exit 1 done # 2)店舗ID-店舗名テーブルと店舗毎販売実績テーブルを # JOINして、更にShift-JIS形式CSVファイルとして # 出力 cat TMP-DIR/URE | join2 key=1 TMP-DIR/TENPONAME - | tr " " "," | nkf -sLwx > OUT-DIR/URE.CSV # 1:店舗コード 2:店舗名 3:販売数 4:販売額
リスト3と4は、リスト1と2が生成するデータを入力データとしている。入力データは別プロセスが作成しているのだから、通常の開発手法であれば、データの完成通知と、データ本体を何らかのプロセス間通信で実施したいと考える。しかしこれらのプログラムは、システムで用意されているプロセス間通信の仕組みは使っていない。使っているのはファイルだけだ。
リスト1、2は、出力データファイルを作る。ただし、出力データファイルはアトミックに作り終えられるとは限らないため、完成した時点でその証となるセマフォとしての空ファイルを同じ場所に作るようにしている※1。
リスト3、4は最初、セマフォファイルが作成されるのを待つ。そして、セマフォファイルが作成されたことが確認できた時点で、自分の出力すべきファイルの生成を開始する。
リスト3、4では、セマフォファイルが確認できないと60秒待つ。前工程のファイルが完成してから最大60秒間の無駄が発生する。このため、リスト1、2側のプロセスからリスト3、4のプロセス側へ、生成完了通知をシグナル等で伝えればよいと考えるところだ。しかし、それはユニケージ開発手法の作法の考えに合わない。自律性を下げるからだ。
たとえば、システムの仕様変更によってリスト1のデータを新たに必要とするリスト5が現れたらどうだろう。リスト1が、自分の作り出すファイルを必要としているプロセスに完成通知をしなければならないルールになっていたら、プロセスが増減する度にリスト1自身にも手を加えなければならない。
自律性の高いシステムを構築するうえで、ファイルの活用は大変有効だ。上手なシステム設計をするには、人手の作業だったらこれをどう作業分担し、書類をやりとりするか。そこを観察したうえで、プロセスやファイルを使っていかに表現するかを考えることが肝要といえる。
※1 より厳密に説明すると、touch(1)コマンドによるファイルの作成は必ずしもアトミックに処理されない。より厳密に処理する場合にはシンボリックリンクの作成を持ってアトミックな処理とする。シンボリックリンクの作成はアトミックに処理される。
※ ユニケージはユニバーサル・シェル・プログラミング研究所の登録商標。
※ usp Tukubaiはユニバーサル・シェル・プログラミング研究所の登録商標。
※ 本ページで公開されているプログラムとそれに付随するデータの著作権およびライセンスは、特に断りがない限りOpen usp Tukubai本体と同じMITライセンスに準拠するものとする。
USP MAGAZINE 2012 autumn「第四回 ユニケージエンジニアの作法」より加筆修正後転載。