Skip to content

refactor: route native lookups through a typed registry and one host module - #1117

Merged
kvlonge merged 4 commits into
mainfrom
feat/chi599-batch-1
Oct 16, 2026
Merged

kvlonge merged 4 commits into
mainfrom
feat/chi599-batch-1

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Why

Rust looked up its own native classes and Python entry points by string at about 2,500 call sites, re-importing modules on every call; renaming a Python target only failed when that path ran. Graph walks were copied per caller, and abandoned scenario workers could abort the interpreter at exit.

Changes

  • Typed native registry for records, enums, errors and functions, checked at module init; string self-lookups and by-name class resolution removed.
  • sqlbuild._native_host: one lazily resolved host module listing every staying-Python entry point Rust may call, mirrored by one Rust table with typed per-edge wrappers; an import test fails on any rename.
  • Generic graph walks in sqlbuild-core replace about 30 per-caller copies (closures, paths, shortest path, dependency order, cycles) with each caller's ordering preserved.
  • Scenario workers are joined before interpreter finalization, with a notice while waiting; a further Ctrl-C ends the wait quietly.

Verification

  • make test and make check-ci passed with all optional dependencies available.
  • Compiler differential: 371 projects, unchanged goldens. Planner differential: 11 projects matched the main baseline.
  • Compile outputs and exit codes match the reference on synthetic and private compile-only projects.
  • Windows cross-check of the whole workspace passed; scenario exit regression tests pass.
  • Independent review: no blocking findings; both low findings fixed.

Rust no longer imports sqlbuild modules by path. Classes, enums, errors and
functions that sqlbuild._native registers are reached through
records::registry (RecordId, ErrorId, NativeAttr), checked against the
registration tables when the module initialises. Staying-Python entry points
(adapter, user code, executor and runtime, third-party, public facade) are
reached through the native_host table and sqlbuild._native_host, which
resolves each name lazily. shape_classes.rs and hosted_native_name are
removed. The native module path scanner checks every host table row.
Add `sqlbuild_core::graph_walk` with walks generic over the key type and
the visited set: breadth-first reach (optional depth), directed path
nodes, shortest path to a goal, Kahn order with a caller tie-break queue,
depth-first post-order and depth-first cycle search.

Replace the per-crate copies: closures and path nodes over DAG artifacts,
the project graph, lineage commands, dbt graphs, Python selection, diff
selection, Python-keyed graph edges, loader graphs, SQL-test CTE reads
and helper scopes, macro export dependencies, rule import closures and
type recovery; Kahn orders for planner keys, Dagster events and macro
module loads; post-orders for loaders, SQL-test model chains and
migration discovery; and cycle searches for Python nodes and macros.
Each caller keeps its traversal order, tie-breaks and messages.
Scenario workers are daemon threads that run native scenario planning,
which calls back into the adapter. When a run is abandoned, the main
thread exits while a worker can still be inside that native frame, and
finalization ending the thread there aborts the process with "exception
not rethrown". Register an exit hook when workers start that joins the
named scenario workers within a bounded time, so they leave native code
first. Add a fresh-process regression test that abandons workers inside
a native frame calling slow Python.
@kvlonge
kvlonge enabled auto-merge (squash) October 16, 2026 07:26
@kvlonge
kvlonge merged commit d089039 into main Oct 16, 2026
76 of 78 checks passed
@kvlonge
kvlonge deleted the feat/chi599-batch-1 branch October 16, 2026 08:19
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