Release the GIL during evaluation, and decide on free-threaded (cp314t) support

Đang mở
#45 3 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
42/100
Loại issue
Tính năng
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python, rust
Lĩnh vực
backend, ci-cd, performance, testing

Hướng nghiên cứu

Bắt đầu từ evaluate() và Program.execute(), sau đó chạy compile_execute_benchmark.py để đo overhead của detach/attach so với ngưỡng đã nêu. Kiểm tra Context, stdlib Env dùng chung và cache theo từng Context về tính an toàn khi free-threaded, đồng thời kiểm tra ma trận CI của maturin-action. Được xem là hoàn tất khi việc đánh giá đồng thời được bao phủ bởi các bài kiểm thử, lựa chọn GIL-release được benchmark và các wheel cp314t được bao gồm nếu được hỗ trợ.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

enhancement

Problem

evaluate() and Program.execute() hold the GIL for the entire Rust-side evaluation. A Python program that evaluates CEL from several threads therefore serialises on the interpreter even though the work is pure Rust once the context has been converted. This matters for the policy-engine style of use (many rules × many requests) that the README leads with.

Proposal

  1. Release the GIL around program.execute() with py.detach(|| ...) (PyO3 0.29's spelling of allow_threads). The pieces already have the right bounds: cel::Program is a plain AST, cel::Context<'static> is Send + Sync (its Val, Function and VariableResolver traits all require it), and the Python-callback wrappers already do their own Python::attach, so a callback simply re-acquires the GIL when it runs. Conversion of the result back to Python happens after re-attaching.
  2. Measure the fixed cost. Detach/attach is on the order of tens of nanoseconds, but a trivial x + y executes in ~0.15 µs, so unconditional detaching could be a visible relative slowdown for tiny expressions while being a large absolute win for anything heavier or for multi-threaded callers. Options, in order of preference:
    • detach unconditionally if the overhead measures under ~10% on the compile_execute_benchmark.py cases;
    • otherwise detach only when the context has no Python functions and no resolver (that's when the evaluation cannot need the GIL), which is cheap to know from the Context;
    • an explicit execute(ctx, release_gil=...) knob is a last resort.
  3. Free-threaded Python. PyO3 0.29 supports the free-threaded build when the module opts in with #[pymodule(gil_used = false)]. Before doing that, audit: Context mutators are &mut self (PyO3's borrow checker turns concurrent mutation into an error rather than a data race), the shared stdlib Env is a LazyLock, and the per-Context cache proposed in the Context-reuse PR is behind a Mutex. Then add cp314t wheels to the CI matrix (maturin-action needs the interpreter listed explicitly; --find-interpreter won't pick it up).

Non-goals

Context itself is documented as not thread-safe for concurrent mutation; that stays. Concurrent evaluation against a shared Context is already fine and is now pinned by tests.

Ngôn ngữ chính
Python
Star
43
Fork
4
Merge trung bình
9 giờ 57 phút
Pull request đã merge (30 ngày)
14

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của hardbyte/python-common-expression-language

Tất cả issue của hardbyte/python-common-expression-language

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.