要約

  • Clickのconnectionは、パケットを受け渡せる前向きの経路を表す。実際の通過記録でも、どちらの端が転送を起動したかを示す記号でもない。
  • pushでは送信元から制御が前へ進む。pullでは宛先から要求が後ろへ進み、得られたパケットは矢印の向きへ戻る。明示的なQueueが二つの時間を接続できる。
  • グラフは責任を読める形にするが、port type、初期化、キュー状態、schedulerの選択、device完了、受信結果は別々の証拠として残る。

矢印を実行履歴として読まない

Clickはルーター処理をelementへ分割する。デバイスから読む、ヘッダーを検査する、経路を調べる、分類する、数える、蓄える、送るという仕事を、細かい部品として組み合わせる。接続は有向グラフになり、そのedgeはパケットhandoffの可能な経路を表す。

2000年のTOCS論文にはEddie Kohler、Robert Morris、Benjie Chen、John Jannotti、M. Frans Kaashoekが名を連ねる。論文が「可能な経路」と書くのは慎重である。設定にedgeがあっても、特定のパケットがそこを通ったとは限らない。さらに、パケットがAからBへ進むことは、Aが必ずBを呼ぶことを意味しない。

図が答えるのは構造であり、portの契約が答えるのは起動である。この二つを一つにすると、出力deviceが準備できないための停止を上流の不足と誤認したり、設定上の枝を実際に選ばれた枝として報告したりする。

到着が先に起きるpush

受信deviceには、下流が要求していなくてもパケットが到着する。FromDeviceのようなelementは、その出来事を受けて次のpush interfaceを呼ぶ。制御はパケットとともに前へ進み、消費、破棄、保存のいずれかへ至る。

起点が時機を持つことと、全経路を支配することは違う。classifierは別の出力を選べる。検査は不正なpacketを捨てられる。有限のqueueは受け入れを拒むことがある。入口の受信counterは、出口での送信完了を証明しない。

追跡には、device event、実行中configurationのidentity、起動したelement、選択されたbranch、各境界の結果が必要になる。集計counter同士を後で比較しても、保存されなかったpacket identityは復元できない。

空きができた側から始まるpull

送信deviceは、自分が送れる時に次のpacketを必要とする。Clickでは宛先側elementがpullを始め、要求がconnectionを逆向きにたどる。上流はpacketを返すか、現在は何もないと答える。

Kohlerの博士論文にある単純なrouter図では、push中のcontrol flowは受信側から前へ、pull中のcontrol flowは送信側から後ろへ進む。一方、packetは常に前へ進む。同じ矢印に、異なる開始点の履歴が存在する。

この規則によってschedulerも部品になる。複数のpull inputと一つのpull outputを持ち、下流から要求されると入力を一つ選んで問い合わせる。配置は決定点を示す。しかし図だけでは、ある時刻に何を選んだか、空だった入力はどれか、待ち続けたsourceがあるかは分からない。

Queueは時間差の所有者である

基本例では、受信側のpush領域と送信側のpull領域の間にQueueがある。到着packetはinputへpushされ、FIFOで保持される。送信deviceが準備できるとoutputからpullし、先頭packetを得る。

Queueを独立elementにすることは、二つの時計が一致しないという告白でもある。到着とserviceの間の時間を、どこかが引き受けなければならない。Clickはそれを大きなprocedureの内部へ隠さず、名前、容量、port、観測可能なstateを与えた。

ただしenqueue成功の証拠範囲は狭い。そのmemory queueが受け入れたことは示せるが、障害後の永続性、最大待ち時間、将来のscheduler選択、hardware送信、遠端受信は示さない。dequeueも、そのqueueから出たという一段の事実である。

FIFOはシステム全体の公平性でもない。複数queueが一つのschedulerに集まる場合があり、queue以前でdropする場合もある。notification、batch、device readinessがpullの頻度を変える。明示化は責任を狭くするが、結果を万能にはしない。

port typeが矛盾を実行前に止める

稼働するClick routerのportはpush、pull、または接続相手に合わせるagnosticとして振る舞う。push同士はpush connection、pull同士はpull connectionになる。pushとpullを直接つなぐことはillegalである。

これは最小限の共通仕様として働く。別々の作者がelementを作り、中央の審査者に個々の組合せを許可してもらわなくてもよい。ただし次の転送を誰が開始できるかについては一致しなければならない。矛盾は評判や裁量ではなく、初期化時の決定的な検査で拒否できる。

SMP Clickの論文は、configuration fileをparseし、routerを作り、initializeを試し、成功した場合にだけinstallしてroutingを始めると説明する。リポジトリに設定があること、図が表示されたこと、syntax checkを通ったことは、実行中datapathの証拠ではない。

最適化された呼び出しには系譜が要る

細かいelement境界には呼び出しcostがあり、重複計算も起こりうる。Kohler、Morris、Chenはconfiguration全体にcompilerのような最適化を適用した。Clickのtool群はclassifierのspecialize、dead code除去、virtual call削減、alignment検査、複数router定義の結合なども行う。

その結果、論理グラフのedgeと実行時のfunction callは一対一でないことがある。グラフは責任の説明として有効なままだが、調査にはsource configuration、変換手順、生成物、build identity、installされたinstanceの連鎖が必要になる。

連鎖がなければ、原図をliteral traceとして扱う誤りと、最適化binaryを説明不能なblack boxとして扱う誤りが同時に起きる。Running-Code Primacyは設計文書を捨てることではない。文書がどのcodeに変換され、検証され、採用されたかを示すことである。

一人の名前に全ての呼び出しを集めない

Harvardの公式profileはClickをKohlerのprojectとして挙げ、journal paperではKohlerが筆頭著者である。MIT thesisはarchitectureと言語toolを詳しく展開した。同時に、主要論文にはMorris、Chen、Jannotti、Kaashoekが並び、language reportにはMassimiliano Polettoも参加し、repositoryにはその後の多数のcontributorがいる。

共同作業を一人の英雄へ変換することは、人の歴史で同じ読み違いをすることになる。一本の矢印を見て、一つの端点が全てを呼んだと思い込むからである。Kohlerの貢献は、責任を小さく構成可能にし、起動者を宣言し、実行結果を別の証拠として要求する方法にこそ明瞭に現れる。

出典