Skip to content

feat: add convergence layer - #39

Merged
somasekimoto merged 10 commits into
mainfrom
feature/add-convergence-layer
Dec 2, 2025
Merged

somasekimoto merged 10 commits into
mainfrom
feature/add-convergence-layer

Conversation

@Yu-da-1

@Yu-da-1 Yu-da-1 commented Oct 13, 2025

Copy link
Copy Markdown
Member

Description

  • 収束レイヤー convergence/ を新設し、ContentMetadataMergePolicyConflictResolver などの仕組みを導入。LWW ポリシー実装を含め、ポリシー拡張の土台を整備。
  • Repo 層を拡張し、自動マージ (check_and_merge) を収束レイヤーと DAG の連携で実行。マージ操作は内部トリガーのみ許可する構造に変更。
  • DAG の API を整理し、add_genesis_node / add_child_node / get_nodes_by_genesis など因果関係を意識した命名とメタデータ保持のフローに統一。
  • CRDT 側の OperationTypeMerge を追加し、マージ結果を操作履歴として保存できるようにした。CLI を新アーキテクチャに合わせて更新。

Notes & open questions

  • 現状ポリシーは LWW のみで、ContentMetadata::policy_type を使った拡張ポリシー設計・実装は今後の課題。
  • メタデータ伝播は基本パスで担保しているが、カスタムポリシー導入時にテストを拡充する必要がある。
  • 手動マージ (OperationType::Merge を外部から投入) は未サポート。ユースケースや安全策が固まり次第検討する。今は内部自動マージのみに限定。

@Yu-da-1
Yu-da-1 marked this pull request as ready for review October 15, 2025 12:02
Comment thread src/convergence/metadata.rs Outdated
pub struct ContentMetadata {
/// Policy type name (e.g. "lww", "text", "custom-policy").
/// When this is `None`, it falls back to the default policy (currently "lww").
policy_type: Option<String>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[imo]
PolicyTypeっていうenumタイプにしといたほうがいいかも?

Comment thread src/repo.rs Outdated
Comment on lines +202 to +215
let merge_cid = self.dag.add_child_node(
merge_node.payload().clone(),
heads.clone(),
*genesis,
merge_node.metadata().clone(),
)?;

let mut merge_op = Operation::new(
*genesis,
OperationType::Merge(merge_node.payload().clone()),
"auto-merge".to_string(),
);
merge_op.parents = heads;
self.state.apply(merge_op)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ask]

dag.add_child_nodeと、state.apply どっちかが失敗してしまったときにデータの整合性って問題なく取れそうですか?

常に両方のデータを更新する必要がある場合は、RDBMSでいうところの "transactionを張る" という処理が必要だと思います。levelDBだと デフォルトでそういう機能はないので、writebatchとか使って自前で実装する必要がある気がしています。

let inputs = self.collect_inputs(heads, dag)?;
let merged_payload = policy.resolve(&inputs);
let metadata = self.merge_metadata(heads, dag)?;
let timestamp = Self::current_timestamp()?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ask]
今回の実装と外れるかもなのですが、この関数ってnano秒を返さなくていいんでしたっけ?
next_monotonic_timestamp 関数はnano秒を返してるはずで、そこと揃えなくていいのか気になりました。

Comment thread src/repo.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[should]
そういえばここも失敗しちゃうと前の処理で更新したDBのデータと整合性合わない気がする

@Yu-da-1 Yu-da-1 mentioned this pull request Nov 9, 2025
@somasekimoto
somasekimoto merged commit d22a044 into main Dec 2, 2025
4 checks passed
@somasekimoto
somasekimoto deleted the feature/add-convergence-layer branch December 2, 2025 14:51
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.

3 participants