-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(payload): add support for stack of payload builders #11004
feat(payload): add support for stack of payload builders #11004
Conversation
Originally posted by @mattsse. FYI @aroralanuk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the original issue requested a stack where you could use more than one type of payload builder - in this, because of the single generic, you can only do multiple of one type of payload builder. So this needs to be changed to support two different payload builders with two different types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think this works because it assumes all builders are the same type?
|
||
/// A stack of payload builders that can be used in sequence. | ||
#[derive(Clone, Debug)] | ||
pub struct PayloadBuilderStack<B>(Vec<B>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
take a look at this type for reference:
https://docs.rs/tower/latest/tower/layer/util/struct.Stack.html
because this has two instances, this allows "stacking" of multiple different types, which can be nested and is very flexible, for example: Stack<Stack<A, B>, C>
etc.
A vec would work if all payloadtypes are the same but ideally we can be a bit more flexible here by using two generics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I understand now, will fix soon!
type Attributes = B::Attributes; | ||
type BuiltPayload = B::BuiltPayload; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we do Stack<A,B>
then these could be Either<A,b>
:
https://docs.rs/futures/latest/futures/future/enum.Either.html
&self, | ||
args: BuildArguments<Pool, Client, Self::Attributes, Self::BuiltPayload>, | ||
) -> Result<BuildOutcome<Self::BuiltPayload>, PayloadBuilderError> { | ||
let mut args = Some(args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and these functions would then do a match on the Either
and delegate the to A or B, we likely needs some mapper helpers on BuildArguments and Outcome
crates/payload/basic/src/lib.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these changes we don't need, because those are independent of the payloadbuilder type itself
@mattsse does this feel still too restrictive, we can do:
|
BasicPayloadJobGenerator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool, the last thing that is missing is changing the stack attribute types
type Attributes = L::Attributes; | ||
type BuiltPayload = L::BuiltPayload; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is now no way to determine which builder should be used, hence we should use Either<L::Attr, R::Atrr>
here
ref https://github.com/paradigmxyz/reth/pull/11004/files#r1768054937
It's a bit more verbose now (with the PayloadBuilderAttributes and BuiltPayload implementation for Either and map_payload), but it uses Either<L::Attr, R::Attr> now. @mattsse |
use futures_util::future::Either as EitherFuture; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it might be code duplication, we're not really implementing Future
for an either type here, so it seems better to just hand roll an Either
type for the crate and implement Error
/ PayloadBuilderAttributes
/ BuiltPayload
on it. It would help naming as well
@mattsse Can you merge this? |
ah oops, forgot to pull the trigger ty and sorry for the long delay on this -.- |
Problem
We need a flexible way to combine and sequentially execute multiple payload builders of the same type, allowing for more complex and customizable payload building strategies. Fixes #10438
Solution
Implement a new
PayloadBuilderStack<L, R>
that can hold and execute two builders of potentially different types in sequence, with the ability to nest these stacks for more complex arrangements.Implementation Details
PayloadBuilderStack<L, R>
with two generic type parameters for left and right buildersStack<Stack<A, B>, C>
Testing