Research: should GFQL chains be immutable? (execution re-validates a mutation the product never performs)

オープン
#2,091 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
25/100
issue の種類
機能追加
明瞭さ
説明が足りない
活発さ
活発
技術スタック
python
領域
performance

調査の方向性

Start with graphistry/tests/compute/test_chain_validation_execution.py::test_execution_revalidates_mutated_ast and inspect the AST and chain classes named in the issue (ASTObject, ASTNode, ASTEdge, and Chain). The issue is explicitly a research question with no recommended action: first establish whether users rely on mutation and whether a copy-on-write migration is acceptable. Done means reaching a decision on immutability and its migration path, weighing that against the measured performance gain.

索引モデルが issue の本文から書いたものです。

説明

Research question, not a proposal. Opened to capture an audit finding and decide whether it is worth pursuing; there is no recommended action yet.

The question

GFQL query chains are frozen in practice but explicitly mutable by contract. Every execution re-validates the ops to defend a mutation the product never performs. Is that contract worth its per-query cost, and would enforcing immutability be better?

What the audit found

ASTObject / ASTNode / ASTEdge / Chain are plain classes — not frozen dataclasses, no __slots__, no __setattr__ guard — so anything about them is writable after construction.

Nothing in the product mutates them. Searching graphistry/ outside tests for assignments to op attributes, to chain[i].<attr>, or to Chain.chain after construction returns nothing.

But mutation is a tested, intentional contract. graphistry/tests/compute/test_chain_validation_execution.py::test_execution_revalidates_mutated_ast mutates edge.hops between runs and requires every execution to raise E103, parametrized across:

  • both entry points (chain, gfql)
  • wrapped and unwrapped (Chain(ops) and a raw list)
  • all engines

So this is not defensive coding that crept in. Someone decided a mutated AST must be caught at execution time, every time, however the caller holds it.

What it costs

Measured on LDBC SNB SF0.1, polars, in-process with an A/A control:

ms/query
AST validation before #2088 (seed-lookup) 0.075
after #2088, which removed the redundant second pass on the gfql path 0.038
remaining, i.e. what enforcing immutability could additionally remove ~0.038

#2088 removed one of two passes and only where gfql built the chain in the same call — precisely because the contract above forbids touching the case where a caller supplies their own container. Enforcing immutability would let the remaining pass go for every caller.

The trade

For: validated becomes an invariant rather than a hope; the skip logic and its marker disappear; ~0.038 ms/query back on every query, every engine; a whole class of "did this change under us" reasoning goes away.

Against: it is a breaking API change. Any user code that builds a chain and then adjusts it would start failing, and the behaviour is currently tested, so it is fair to assume someone relies on it. It would need a deprecation path, and the payoff is small in absolute terms.

What would settle it

  1. Is mutating a built chain a use case anyone actually has, or an artifact of the objects being plain classes?
  2. If it is a use case, is replace-style copy-on-write an acceptable migration?
  3. Is ~0.038 ms/query worth a deprecation cycle, or is this only worth doing if immutability is wanted for its own sake (thread-safety, caching by identity, structural sharing)?

Filed from a performance audit; not blocking any open PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_012Me1E7ZdDuGqJGu3mMEzhp

主要言語
Python
スター
2.6k
フォーク
229
平均マージ
1日 5時間
マージ済み PR(30日)
99

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

graphistry/pygraphistry のほかの issue

graphistry/pygraphistry の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。