event の設計

設計目標

イベントストリームは実験の監査記録です。レポートのすべての数値とリプレイされるすべての失敗は、そこから復元できなければなりません。event はこの記録を追記専用かつ行指向に保ち、ストレージの選択をランナーから切り離します。

数学的背景

実行をイベントの系列 e1,e2,…,eNe_1, e_2, \dots, e_N、シンクを畳み込み sk=emit(sk−1,ek)s_{k} = \text{emit}(s_{k-1}, e_k) としてモデル化します。JSONL シリアライズはイベントから行への写像 JJ であり、保存されるストリームは行 J(e1),…,J(eN)J(e_1), \dots, J(e_N) を改行で連結したものです。

この構造から 2 つの性質が導かれます。

  1. 接頭辞について閉じている。 ストリームのどの接頭辞も、より短い実行のストリームです。kk 個のイベントの後にクラッシュしても e1,…,eke_1, \dots, e_k の有効な記録が残り、行を独立に処理するリーダーはそれを利用できます。
  2. 射影は連結と可換。 レポートは行ごとに構築されるため、連結された 2 つのストリームの射影は、それぞれの行の射影から計算されます。ストリームのマージやフィルタリングは単なるテキスト処理です。

tee は 2 つの畳み込みの積です。(s,t)(s, t) を (emit1(s,e),emit2(t,e))(\text{emit}_1(s, e), \text{emit}_2(t, e)) に写すため、1 回のパスで実行をメモリとディスクの両方に保存できます。

設計上の決定

クロージャのレコード

問題。 シンクは状態(配列、ファイルハンドル)を持ち、組み合わされます(tee)。選択肢。 メソッドを持つトレイト、または関数のレコード。選択。 5 つのクロージャからなるレコード。理由。 クロージャはシンクが必要とする任意の状態を捕捉でき、レコードはテスト内でその場で構築でき、tee のようなコンビネータは新しいレコードを返す通常の関数になります。

1 行に 1 つの JSON オブジェクト

問題。 記録はストリーミング可能で、追記可能で、どんなツールからも読めなければなりません。選択。 すべての行に type 判別子と artifact_version を持つ JSONL。理由。 各行が自己記述的なので、リーダーは知らない種類を読み飛ばせ、grep が使え、クラッシュしてもそれ以前の行が壊れることはありません。各行のバージョンにより、異なるバージョンのストリームを連結しても、なお正確に拒否できます。

生の値のみ

観測は 1 つのバッチの反復あたりの時間を持ち、平均、中央値、フィルタリングされた値を持つことはありません。レポートのすべての統計量はこれらの生の値から再計算され、外れ値ポリシーが履歴を書き換えることはできません。

文字列としてのシード

seed は 10 進文字列として書かれます。JSON の数値は倍精度浮動小数点数であり、すべての 64 ビット整数を表現できないためです。2532^{53} を超える整数は丸められてしまいます。

finish はロケーションを返す

finish は記録の行き先(memory://run/…、jsonl://memory/…、ファイル名)を返し、ランナーはそれを要約に格納します。ランナーがファイルについて知らなくても、呼び出し側は証拠の所在を知ることができます。

正しさと不変条件

  • 各 emit 呼び出しは、ちょうど 1 行を書き出す(JsonlSink、streaming_jsonl)か、ちょうど 1 つの要素を追加します(InMemorySink)。
  • すべての行は artifact_version mmka_1 と type を持ちます。
  • tee は順序を保ちます。どのイベントも、左のシンクが右のシンクより先に受け取ります。
  • to_jsonl はイベントごとに 1 行を持ち、行は \n で区切られます。
  • 文字列は JSON エンコーダによってエスケープされるため、行が生の改行を含むことはありません。

採用しなかった代替案

  • 実行ごとに 1 つの JSON ドキュメント。 追記できず、クラッシュするとすべてが失われます。
  • CSV。 入れ子になった証拠(オペランド、フラグ、環境)が収まりません。
  • バイナリ形式。 レビューや issue の報告で読めません。

境界

  • ファイル IO は行いません。行をディスクに書き出すのは呼び出し側の役割です(cli とアプリケーションがこれを行います)。
  • InMemorySink は要約を保持しません。
  • JSONL ライターは、検証ステータスの理由文字列と観測の setup_timing を省略します。
  • リーダーはここにはありません。ストリームを解析するのは report と cli です。