Skip to content

perf(execution): fast-path empty outcome calls - #104

Merged
thomhurst merged 1 commit into
mainfrom
perf/outcome-fast-path
Aug 21, 2026
Merged

perf(execution): fast-path empty outcome calls#104
thomhurst merged 1 commit into
mainfrom
perf/outcome-fast-path

Conversation

@thomhurst

@thomhurst thomhurst commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • bypass context rental and pipeline construction for ExecuteOutcomeAsync when the shield has no strategies
  • preserve synchronous and asynchronous exception capture as Outcome<T>
  • preserve cancellation and execution-metrics behavior

Profiling finding

ExecuteOutcomeAsync did not share the existing empty-pipeline fast path used by ExecuteAsync. A no-strategy outcome call therefore paid for KevlarContext.Rent, continuation construction, and context return on every execution.

Benchmark

BenchmarkDotNet 0.15.8, default job, .NET 10.0.11, Windows 11, Intel Core Ultra 9 185H. Both runs used the same checkout base and machine.

Benchmark Before After Change Allocated
Kevlar_EmptyOutcomeState 110.5 ns 21.28 ns 80.7% faster (5.2x) 0 B -> 0 B

Commands:

dotnet run --project benchmarks/Kevlar.Benchmarks -c Release --no-build -- --filter "*EmptyOutcomeState*"

Validation

  • dotnet build Kevlar.slnx -c Release
  • dotnet run --project tests/Kevlar.Tests -c Release --no-build -- --timeout 5m (612 passed)
  • dotnet run --project tests/Kevlar.AllocationTests -c Release --no-build -- --timeout 5m (2 passed)

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of errors during direct actions so failures are returned consistently instead of causing unexpected interruptions.
    • Preserved successful results for both immediate and asynchronous actions.
    • Execution metrics are now recorded consistently for asynchronous processing.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2262a0d6-d640-4ecf-8775-5bb931ab9458

📥 Commits

Reviewing files that changed from the base of the PR and between 86185a2 and 0d209b4.

📒 Files selected for processing (1)
  • src/Kevlar/Internal/ShieldEngine.cs

Included review availability: Your plan provides up to 10 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

The direct-action execution path now converts synchronous exceptions, completed results, and asynchronous results into Outcome<T> values. Asynchronous handling also records success metrics.

Changes

Direct outcome handling

Layer / File(s) Summary
Direct action execution and asynchronous conversion
src/Kevlar/Internal/ShieldEngine.cs
ExecuteOutcomeAsync now handles synchronous results and exceptions as Outcome<T> values. Incomplete executions use AwaitDirectOutcomeAsync, which converts asynchronous results and exceptions and records success metrics.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 0d209

The change adds a localized fast path for empty outcome executions while preserving exception, cancellation, and metrics behavior; no actionable merge-blocking risk remains after normal checks and review.

Poem

I’m a rabbit in the code,
Hopping where direct actions go.
Errors turn to outcomes neat,
Async paths now land complete.
Metrics mark each success bright.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the fast path added for empty outcome calls in ExecuteOutcomeAsync.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/outcome-fast-path

Comment @coderabbitai help to get the list of available commands.

@thomhurst
thomhurst merged commit 2e44a82 into main Aug 21, 2026
7 of 8 checks passed
@thomhurst
thomhurst deleted the perf/outcome-fast-path branch August 21, 2026 18:16
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