Skip to content

docs: Mermaid-ize GenStage pipeline diagram - #35

Merged
toshi0806 merged 1 commit into
mainfrom
docs-mermaid-architecture
Jun 16, 2026
Merged

docs: Mermaid-ize GenStage pipeline diagram#35
toshi0806 merged 1 commit into
mainfrom
docs-mermaid-architecture

Conversation

@toshi0806

Copy link
Copy Markdown
Member

概要

エコシステム横断 TODO #5(アーキテクチャ図の Mermaid 化と一貫適用)の一環として、README の ## Architecture セクションにある GenStage パイプラインの ASCII 図を Mermaid (graph LR) に変換しました。参照実装は tenbin_cache PR #106 です。

コード照合の結果

README の既存記述を鵜呑みにせず lib/ の実コードと照合しました。各ステージの実態:

  • Producer = {:producer, ...}lib/elixir_dnstap/producer.ex)— host が enqueue/2GenStage.cast)で投入、demand ベースのバックプレッシャー + 内部キュー
  • BufferStage = {:producer_consumer, ...}lib/elixir_dnstap/buffer_stage.ex)— ElixirDnstap.EncoderProtocol Buffers にエンコード(ステートレス変換)
  • WriterConsumer = {:consumer, ...}lib/elixir_dnstap/writer_consumer.ex)— writer_module.write/1 に委譲
  • Writer.{File,TCP,UnixSocket} = GenServer(lib/elixir_dnstap/writer/)— Frame Streams フレーミング(FrameStreams.encode_data_frame)と実 I/O
  • 起動構成は lib/elixir_dnstap/supervisor.ex で確認(Producer → BufferStage → WriterConsumer + 選択された Writer を :one_for_one で起動)

既存 ASCII との差分(修正点)

既存 ASCII 図は 2 段目ラベルで BufferStage → Encoding / WriterConsumer → Frame Streams としており、Frame Streams 段を WriterConsumer の下に誤配置していました。実際には:

  • Protocol Buffers エンコードは BufferStage で行う
  • Frame Streams フレーミングは Writer に委譲される(BufferStage の moduledoc の Design Note: "Frame Streams encoding is delegated to the Writer ... to avoid double encoding")

この 2 つは別個のエンコード段であることを Mermaid 化と同時に修正し、補足 note に明記しました。

スタイル方針

  • pipeline 系なので graph LR
  • 実線 --> = GenStage の subscription chain(下流が上流を subscribe)
  • 点線 -. label .-> = ランタイム関係(host からの enqueue cast / write/1 委譲 / Frame Streams I/O)
  • classDef 等の装飾は使わず構造の明快さを優先
  • ノードラベルは "名前<br/>(役割)" 形式
  • 図の直後に凡例・コンポーネント説明・補足 note を prose で併記

変更後の Mermaid

graph LR
  Host["Host app<br/>(log_client_query/6)"]
  Producer["Producer<br/>(GenStage :producer)"]
  BufferStage["BufferStage<br/>(GenStage :producer_consumer)"]
  WriterConsumer["WriterConsumer<br/>(GenStage :consumer)"]
  Writer["Writer.{File,TCP,UnixSocket}<br/>(GenServer)"]
  Output["File / TCP / Unix socket"]

  Producer --> BufferStage
  BufferStage --> WriterConsumer
  WriterConsumer --> Writer

  Host -. "enqueue (GenStage.cast)" .-> Producer
  WriterConsumer -. "write/1" .-> Writer
  Writer -. "Frame Streams I/O" .-> Output
Loading

テスト

Lefthook(format / test / credo)全 green(114 tests passed, credo no issues)。docs のみの変更です。

## Frame Streams Protocol 配下の START→DATA→STOP 等の小図はスコープ外として変更していません。

Convert the ASCII GenStage pipeline diagram in the Architecture section
to a Mermaid graph LR, verified against lib/ source.

- Solid arrows = GenStage subscription chain, dotted = runtime relations
  (enqueue cast, write/1 delegation, Frame Streams I/O)
- Annotate each stage with its actual GenStage role (:producer /
  :producer_consumer / :consumer) and the writer as a GenServer
- Fix encoding-step mislabeling: Protocol Buffers encoding is done in
  BufferStage, while Frame Streams framing is delegated to the Writer
  (the old ASCII placed Frame Streams under WriterConsumer)
@toshi0806

Copy link
Copy Markdown
Member Author

Review convergence summary

レビュー対応ループを実施し、収束を確認しました。

CI ステータス (head d274714)

  • ci / Test on OTP 27.3.4.4 / Elixir 1.17.3: success
  • ci / Test on OTP 29.0.2 / Elixir 1.20.1: success
  • ci / Code Quality: success
  • ci / Dialyzer Analysis (latest): skipped (matrix 設計どおり)

本リポには AI レビュー workflow (review / review) は設定されておらず(.github/workflows/elixir.yml のみ)、review thread / review / comment はいずれもゼロです。actionable な指摘は存在しません。

Mermaid 図の独立検証 (lib/ 突き合わせ)

README の GenStage パイプライン図を lib/ のソースと突き合わせて検証し、全項目が実装と一致することを確認しました。修正は不要です。

  • Producer = :producerlib/elixir_dnstap/producer.ex ({:producer, state})
  • BufferStage = :producer_consumer、Protocol Buffers エンコードを担当 — lib/elixir_dnstap/buffer_stage.ex ({:producer_consumer, ...}, alias ElixirDnstap.Encoderencode_client_query/response)
  • WriterConsumer = :consumerlib/elixir_dnstap/writer_consumer.ex ({:consumer, state, ...})
  • Writer = GenServer、Frame Streams framing を Writer 側に委譲 — lib/elixir_dnstap/writer/file.ex (GenServer), writer/behaviour.ex (Frame Streams)
  • 実線 = subscription chain(GenStage.sync_subscribe)、点線 = ランタイム関係を正しく区別
  • enqueue (GenStage.cast)producer.exenqueue/2GenStage.cast/2
  • write/1 委譲 — writer_consumer.exwriter_module.write(frame)file.exdef write(message)(内部で GenServer.call)。なお behaviour の @callback write/2 は (state, message) の別レイヤであり、ランタイム委譲の write/1 ラベルとは矛盾しません
  • Host app entry log_client_query/6lib/elixir_dnstap.ex@spec log_client_query/6(packet, client_addr, client_port, server_addr, server_port, socket_protocol)

結論

  • 対応した実体的指摘: なし(図はコードと完全一致)
  • 却下/据え置きした指摘: なし(指摘自体が存在しない)
  • 図のスタイルも方針(graph LR / classDef 不使用 / 実線=subscription・点線=ランタイム / "名前<br/>(役割)" ラベル)に準拠

収束済みです。マージは行いません。

@toshi0806
toshi0806 merged commit ae6c1ec into main Jun 16, 2026
4 checks passed
@toshi0806
toshi0806 deleted the docs-mermaid-architecture branch June 16, 2026 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant