feat(stages)!: swap StageDelegate for IContinuation, resolve lazily - #3
Merged
Merged
Conversation
An interface can grow an InvokeAsync overload that takes arguments. A delegate signature cannot, not without breaking every stage that exists. Each level now resolves from the container the first time it runs, the handler included, so a stage that short-circuits never builds what sits below it. A container failure comes out of the next.InvokeAsync() call that reached the broken level, where the stages around it can catch it. A dispatch through N stages allocates N objects instead of 2N+1. The per-level delegate and the per-dispatch stage array are both gone, and a repeated next call allocates nothing. Three stages cost 192 bytes on net10.0 against 416 before. The broken-contract failures throw HandlerNullTaskException, StageNullTaskException, and OverlappingNextCallException instead of a plain InvalidOperationException. Each carries the type at fault in a property. The two null-task types share an abstract NullTaskException base, so one catch clause covers both. BREAKING CHANGE: StageDelegate<TResponse> and StageDelegate are removed. A stage takes IContinuation<TResponse> or IContinuation and calls next.InvokeAsync() where it called next().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An interface can grow an InvokeAsync overload that takes arguments. A delegate signature cannot, not without breaking every stage that exists.
Each level now resolves from the container the first time it runs, the handler included, so a stage that short-circuits never builds what sits below it. A container failure comes out of the next.InvokeAsync() call that reached the broken level, where the stages around it can catch it.
A dispatch through N stages allocates N objects instead of 2N+1. The per-level delegate and the per-dispatch stage array are both gone, and a repeated next call allocates nothing. Three stages cost 192 bytes on net10.0 against 416 before.
The broken-contract failures throw HandlerNullTaskException, StageNullTaskException, and OverlappingNextCallException instead of a plain InvalidOperationException. Each carries the type at fault in a property. The two null-task types share an abstract NullTaskException base, so one catch clause covers both.
BREAKING CHANGE: StageDelegate and StageDelegate are removed. A stage takes IContinuation or IContinuation and calls next.InvokeAsync() where it called next().