Skip to content

feat: change Plugin handler to async for performance - #49

Merged
araujof merged 1 commit into
devfrom
feat/rust_async_handler_on_dev
May 11, 2026
Merged

feat: change Plugin handler to async for performance#49
araujof merged 1 commit into
devfrom
feat/rust_async_handler_on_dev

Conversation

@terylt

@terylt terylt commented May 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Collapses HookHandler<H> and AsyncHookHandler<H> into a single async-by-default trait. Plugin authors now write
async fn handle(...) regardless of whether the body actually awaits anything — handlers with no .await compile to
a trivially-ready future that LLVM inlines, so there's no observable cost over a plain function.

Why

The previous design had HookHandler<H> (sync) and AsyncHookHandler<H> (async) with a blanket impl auto-promoting
sync to async. Two traits, one keyword of difference (fn vs async fn). The only real benefit of keeping them
separate was a compile-time forcing function preventing .await on the hot path — thin value for the cognitive
overhead of two traits in docs, error messages, and bounds.

One trait, one bound, one signature. Authors decide whether to await based on what they need, not which trait they
implement.

What changed

  • HookHandler<H>::handle is now async fn (native AFIT, returns impl Future + Send)
  • Deleted the sync HookHandler<H> trait and the auto-promotion blanket impl
  • All sync plugin impls (test plugins, demos, FFI test plugin, go-demo plugins) gained one async keyword

No behavior change

  • Sync-style plugins (no .await in body) compile to the same machine code via inlining
  • Async plugins work exactly as before
  • The plugin registration API is unchanged: register_handler::<H, _> accepts both kinds

Test plan

  • make ci green: 213 cpex-core tests + 8 cpex-ffi tests + 51 Go tests, clippy clean, fmt clean
  • cargo run --example plugin_demo produces identical scenario output (including the awaiting RemoteAuthz
    plugin)
  • cargo run --example cmf_capabilities_demo produces identical output
  • Two new tests in manager.rs cover the awaiting-handler path: test_async_handler_registers_and_invokes,
    test_mixed_sync_and_async_handlers_in_same_hook

@terylt
terylt marked this pull request as ready for review May 7, 2026 22:38
@terylt
terylt requested review from araujof and jonpspri as code owners May 7, 2026 22:38
@araujof araujof changed the title feat: change Plugin handler to async for performance. feat: change Plugin handler to async for performance May 8, 2026
@araujof araujof self-assigned this May 8, 2026
@araujof araujof added enhancement New feature or request Rust labels May 8, 2026
@araujof araujof added this to CPEX May 8, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in CPEX May 8, 2026
@araujof araujof added this to the 0.2.0 milestone May 8, 2026
@araujof araujof moved this from Backlog to In review in CPEX May 8, 2026

@araujof araujof left a comment

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.

LGTM; clean, well-scoped change.

Good things:

  • The Async Fn In Trait approach
  • Placement of the + Send bound
  • The type-erasure composition

All core tests + FFI tests + Go tests pass, both examples run correctly, clippy is clean.

The RemoteAuthz demo is a nice addition: lock drop before await, initialize-time loading, good pattern to copy.

A few suggestions for follow-up (none blocking):

  1. Doc warning on blocking calls — now that handle is async, a one-liner warning that std::thread::sleep / blocking HTTP inside the body starves the tokio runtime (use spawn_blocking instead) would save someone a debugging session, especially through the FFI shared runtime path.
  2. Concurrent-mode async test — the two new tests use Sequential mode. A variant with PluginMode::Concurrent would cover the full AFIT → adapter → JoinSet::spawn chain.
  3. Context snapshot note — worth documenting that &mut PluginContext is a snapshot in concurrent mode (mutations don't propagate across handlers). More likely to bite someone now that async makes .await-heavy handlers natural.
  4. MSRVrust-version = "1.75" in workspace Cargo.toml would give downstream consumers a clean error instead of a confusing syntax failure.

@araujof
araujof merged commit c1659fb into dev May 11, 2026
@github-project-automation github-project-automation Bot moved this from In review to Done in CPEX May 11, 2026
@araujof
araujof deleted the feat/rust_async_handler_on_dev branch May 11, 2026 16:05
monshri pushed a commit to monshri/contextforge-plugins-framework that referenced this pull request May 27, 2026
monshri pushed a commit to monshri/contextforge-plugins-framework that referenced this pull request Jun 8, 2026
araujof pushed a commit that referenced this pull request Jun 10, 2026
Co-authored-by: Teryl Taylor <terylt@ibm.com>
araujof added a commit that referenced this pull request Jun 10, 2026
* feat: initial Rust Core (cpex-core and cpex-sdk) (#13)

* feat: initial revision rust core.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: addressed comments in PR. Updated PluginContext to match spec.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

---------

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Co-authored-by: Teryl Taylor <terylt@ibm.com>

* feat: CPEX Rust config (#38)

* feat: added yaml and routing rule support.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added example code to show how to load manager and plugins.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fixes: updated plugin errors, configs to more match python.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

---------

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Co-authored-by: Teryl Taylor <terylt@ibm.com>

* feat:  RUST with CMF and extensions. (#44)

* feat: initial revision rust core.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: addressed comments in PR. Updated PluginContext to match spec.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added yaml and routing rule support.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added example code to show how to load manager and plugins.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fixes: updated plugin errors, configs to more match python.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: RUST CMF initial revision.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added invoke named support, added constants, fixed reviewed code.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added owned extensions and did some refactoring.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

---------

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
Co-authored-by: Teryl Taylor <terylt@ibm.com>
Co-authored-by: Frederico Araujo <frederico.araujo@ibm.com>

* feat: cgo Go bindings (#45)

* feat: initial revision rust core.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: addressed comments in PR. Updated PluginContext to match spec.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added yaml and routing rule support.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added example code to show how to load manager and plugins.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fixes: updated plugin errors, configs to more match python.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: RUST CMF initial revision.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added invoke named support, added constants, fixed reviewed code.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added owned extensions and did some refactoring.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added cgo and golang bindings, examples and readme.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* address P0/P1/P2 review findings (except #17)

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: address remaining P2/P3 review findings + testing gaps

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* docs: add CPEX Go public API spec

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* docs: renamed document

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* feat(cpex-rust): CGO review passes 1-11 + lint cleanup + Makefile targets

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: address linting issues, updated makefile to support building examples.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* docs: updated the go spec to reflect recent changes.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

---------

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
Co-authored-by: Teryl Taylor <terylt@ibm.com>
Co-authored-by: Frederico Araujo <frederico.araujo@ibm.com>

* docs: intial rust specification (#50)

Co-authored-by: Teryl Taylor <terylt@ibm.com>

* feat: change Plugin handler to async for performance (#49)

Co-authored-by: Teryl Taylor <terylt@ibm.com>

* fix: missing cmf-demo main.go file and gitignore fix that missed it (#52)

Co-authored-by: Teryl Taylor <terylt@ibm.com>

* feat: initial APL Rust implementation (#60)

* fix: initial revision APL.

* feat: apl-cpex bridge crate + plugin-registry-driven hook dispatch

* feat: add support for plugin calling in APL routes.

* feat: add more APL plugin support, unified config

* feat: added cedar direct PDP.

* feat: add identity hook and extensions.

* feat: added token delegation hooks and tests.

* feat: added plugin for jwt token identity, oauth and biscuit delegation, cedarling PDP.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* fix: updated identity and delegation to support keycloak. added delegate() function, and identity sections.

* fix: added some sample plugins, added updates to support cedar.

Signed-off-by: Teryl Taylor <terylt@ibm.com>

* feat: added session support, serialize and parallel and full effects capabilities.

* feat: add ffi pre-built .a library

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* chore: add workflow_dispatch target

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* fix: critical and high issues from review.

* feat: add APL FFI and go bindings

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* chore: add musl tools to musl runners

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* fix: potential double free after use bug.

* chore: update Go module paths after repo rename to cpex

* feat: map identity extension into cpex ffi

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* feat: add cpex_invoke_resolved abi

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* fix: has_hook_for handling

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* chore: update headers

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

---------

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
Co-authored-by: Frederico Araujo <frederico.araujo@ibm.com>

* fix: session binding

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* chore: updated comments

Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>

* tests: added more session tests for Tier 1 ids.

---------

Signed-off-by: Teryl Taylor <terylt@ibm.com>
Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
Co-authored-by: terylt <30874627+terylt@users.noreply.github.com>
Co-authored-by: Teryl Taylor <terylt@ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request framework Rust

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants