Skip to content

perf(dispatch): hot-path GIL coalescing and Arc-shared route metadata - #86

Merged
ZhuchkaTriplesix merged 3 commits into
devfrom
issue-76-hot-path-cloning
Apr 27, 2026
Merged

perf(dispatch): hot-path GIL coalescing and Arc-shared route metadata#86
ZhuchkaTriplesix merged 3 commits into
devfrom
issue-76-hot-path-cloning

Conversation

@ZhuchkaTriplesix

Copy link
Copy Markdown
Member

Summary

  • Wrap RouteEntry per-request-immutable fields in Arc so the dispatcher clones a pointer instead of copying a Vec / rebuilding a HashSet per request.
  • Coalesce the four scope.getattr(...) calls and the state.read() clone of CORS / security / middleware into a single Python::with_gil block at the start of run_rsgi.
  • Lazy-parse query_string, Authorization / Cookie headers, request body and the kwargs dict — only when the matched route actually needs them.
  • Reorder map_handler_return so the cheap PyString / PyBytes downcasts run before the more expensive __oxyroute_* attribute probes.
  • Inline response mapping + config header merge + RSGI send into a single GIL block via new send_*_sync helpers in src/response.rs, removing one acquire/release per request.

Test plan

  • cargo check
  • make test

Closes #76.

Wrap RouteEntry's per-request-immutable fields (algs, dep_names,
dep_factories, dep_is_async, dep_wants_request, handler_param_names) in
Arc so the dispatcher can `Arc::clone` cheaply instead of copying a Vec
or rebuilding a HashSet on every request.

Refs #76.
Reduce the number of Python::with_gil blocks taken per RSGI request and
defer expensive header/query/body extraction until the handler actually
needs it:

- Snapshot scope.proto/method/path/query_string and clone shared
  middleware/cors/security configs in a single GIL block at function
  entry, replacing ~4 separate getattr round-trips and a state.read.
- Skip body, query, authorization, and cookie parsing for routes that
  don't need them; only build the kwargs dict when at least one
  dependency or named param is configured.
- Reorder map_handler_return type checks so the hot-path PyString /
  PyBytes downcasts run before the more expensive __oxyroute_*
  attribute lookups.
- Inline response mapping + header merging + RSGI send into a single
  GIL block via new sync helpers (send_*_sync) in src/response.rs,
  avoiding an additional GIL acquire/release per request.
- Drop the now-unused async send_bytes / send_head_with_headers helpers.

Behavior is unchanged; existing tests (and the new body-skip coverage
in tests/test_dispatch_fast_fail.py) continue to pass.

Refs #76.
@ZhuchkaTriplesix ZhuchkaTriplesix self-assigned this Apr 27, 2026

@ZhuchkaTriplesix ZhuchkaTriplesix left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

123

@ZhuchkaTriplesix
ZhuchkaTriplesix merged commit 8e5e763 into dev Apr 27, 2026
14 of 16 checks passed
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