Skip to content

perf: replace trivial async implementations with ready - #654

Closed
anishfyi wants to merge 3 commits into
cot-rs:masterfrom
anishfyi:fix-651-ready-futures
Closed

perf: replace trivial async implementations with ready#654
anishfyi wants to merge 3 commits into
cot-rs:masterfrom
anishfyi:fix-651-ready-futures

Conversation

@anishfyi

@anishfyi anishfyi commented Aug 31, 2026

Copy link
Copy Markdown

Related issue or discussion

Fixes #651

Description

Replaces trivial async implementations with regular functions returning immediately-ready futures, removing the unused_async_trait_impl suppressions from production code and generated empty extractors.

Path and UrlQuery use poll_fn rather than ready: storing their result in Ready would add a Send requirement to the deserialized output and narrow the existing generic API. The console transport also uses poll_fn so its stdout side effects remain lazy. Each computation still completes on the first poll without an async state machine.

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Refactor / cleanup
  • Performance improvement
  • Other (describe above)

Checklist

  • I've read the contributing guide
  • Tests pass locally (just test-all) — the full non-ignored workspace and doctest suite passes; ignored service tests could not start because local port 5432 is occupied
  • Code passes clippy (just clippy)
  • Code is properly formatted (cargo fmt)
  • New tests added (not applicable: behavior is unchanged and existing extractor/derive tests cover the changed paths)
  • Documentation updated (not applicable: no user-facing behavior changed)

Commands run

  • cargo test --workspace --all-features
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo fmt --check

Copilot AI lite review requested due to automatic review settings August 31, 2026 06:42
@github-actions github-actions Bot added C-lib Crate: cot (main library crate) C-macros Crate: cot-macros C-core labels Aug 31, 2026

Copilot AI 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.

🟡 Changes recommended

Console::send now performs stdout I/O eagerly at call time via ready((|| { ... })()), which changes Future laziness semantics and can trigger side effects even if the future is dropped without being polled.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR refactors several trivial async implementations into regular functions that return immediately-ready futures, primarily to eliminate clippy::unused_async_trait_impl suppressions and reduce overhead in hot paths while preserving existing APIs (notably using poll_fn for Path/UrlQuery to avoid tightening Send bounds).

Changes:

  • Replaced trivial async fn extractor/handler implementations with fn ... -> impl Future returning core::future::ready(...).
  • Updated core extractors (Request, RequestHead, Method, etc.) and generated FromRequestHead derives to avoid unused-async lints (including a special-case for empty structs).
  • Used core::future::poll_fn for Path and UrlQuery to keep first-poll completion without introducing extra Send requirements on deserialized outputs.
File summaries
File Description
cot/tests/from_request.rs Updates test extractor impl to return an immediately-ready future instead of a trivial async fn.
cot/src/router.rs Refactors test RequestHandler impl to return a ready future and removes lint suppression.
cot/src/request/extractors.rs Converts several built-in FromRequestHead impls to ready(...)-based futures.
cot/src/project.rs Changes Bootstrapper<WithCache>::boot from async fn to returning a ready future and removes lint expectations.
cot/src/error/handler.rs Refactors error extractors to return immediately-ready futures instead of trivial async fns.
cot/src/email/transport/console.rs Converts console email transport send to a ready-future implementation.
cot/src/db/impl_postgres.rs Changes a trivial async init method to return a ready future and adjusts clippy expectations.
cot/src/db/impl_mysql.rs Same as postgres: replaces trivial async init with ready future and updates clippy expectations.
cot/src/cache.rs Refactors Cache::from_config to return an immediately-ready future instead of an async fn.
cot/src/admin.rs Converts AdminModelManagers extractor to return a ready future.
cot-macros/src/from_request.rs Updates derive output to use ready(...) for empty structs while keeping async generation for non-empty ones.
cot-core/src/request/extractors.rs Updates core extractor impls and uses poll_fn for Path/UrlQuery to preserve generic bounds.
Review details
  • Files reviewed: 12/12 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cot/src/email/transport/console.rs
@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cot-core/src/request/extractors.rs 86.20% 2 Missing and 2 partials ⚠️
cot/src/cache.rs 83.33% 1 Missing and 1 partial ⚠️
cot/src/email/transport/console.rs 80.00% 0 Missing and 2 partials ⚠️
cot/src/request/extractors.rs 86.66% 2 Missing ⚠️
cot/src/error/handler.rs 92.30% 1 Missing ⚠️
Flag Coverage Δ
rust 90.13% <88.88%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cot-macros/src/from_request.rs 100.00% <100.00%> (ø)
cot/src/admin.rs 72.91% <100.00%> (ø)
cot/src/db/impl_mysql.rs 100.00% <100.00%> (ø)
cot/src/db/impl_postgres.rs 100.00% <100.00%> (ø)
cot/src/project.rs 88.76% <100.00%> (ø)
cot/src/router.rs 92.21% <100.00%> (ø)
cot/src/error/handler.rs 91.95% <92.30%> (+0.49%) ⬆️
cot/src/cache.rs 84.43% <83.33%> (+0.06%) ⬆️
cot/src/email/transport/console.rs 88.88% <80.00%> (+0.29%) ⬆️
cot/src/request/extractors.rs 90.42% <86.66%> (ø)
... and 1 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@anishfyi

Copy link
Copy Markdown
Author

The Clippy job exposed one additional conditional async case on Rust 1.98: Bootstrapper<WithDatabase>::with_cache has an await only when the cache feature is enabled. Commit 2d8980b now returns the feature-specific async future when cache support is enabled and a ready future otherwise, removing the lint allowances. The exact CI Clippy command, formatting check, and 14 focused project tests pass locally.

@anishfyi anishfyi closed this by deleting the head repository Aug 31, 2026
@anishfyi

Copy link
Copy Markdown
Author

GitHub could not reopen this PR after the deleted fork was recreated because the PR retains the old repository ID. The exact head commit is restored in replacement PR #655.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-core C-lib Crate: cot (main library crate) C-macros Crate: cot-macros

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use core::future::ready instead of #[expect(clippy::unused_async_trait_impl)]

2 participants