Skip to content
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

Experiment: two stage builder approach for custom protocols #2367

Closed
wants to merge 5 commits into from

Conversation

rklaehn
Copy link
Contributor

@rklaehn rklaehn commented Jun 17, 2024

Description

This is like #2358, but instead of having a factory function to create a protocol, it uses a two stage builder approach where you first build a non-accepting node, then add all the promised handlers, and then turn it into a full (accepting, rpc active) node.

Note that I have also changed the signature of the protocol handlers, but that is unrelated to the main difference and a matter of taste I guess. In one case you leave it up to the handlers to make a future long lived, in the other case you force the client to arc the handlers...

Breaking Changes

Notes & open questions

Change checklist

  • Self-review.
  • Documentation updates if relevant.
  • Tests if relevant.
  • All breaking changes documented.

rklaehn added 3 commits June 17, 2024 10:39
first we build a passive node, then spawn. Until the passive node is spawned,
you can add custom handlers.
@rklaehn
Copy link
Contributor Author

rklaehn commented Jun 17, 2024

The custom_protocols example could be made to look like this:

#[tokio::main]
async fn main() -> Result<()> {
    setup_logging();
    let args = Cli::parse();
    // create a new node
    let node = iroh::node::Node::memory()
        .accept(EXAMPLE_ALPN)
        .build();
    let proto = ExampleProto::build(&node);
    node
        .add_handler(EXAMPLE_ALPN, proto))
        .spawn()
        .await?;

Due to the two stage nature you need to use the EXAMPLE_ALPN twice, once before building the unspawned node and once as you add the handler.

I think it is nice, but not quite as compact as the factory fn approach. On the plus side, there is no Box::pin(async move { Ok( needed, and internally the ProtocolMap does not require a RwLock.

For the small example this does not show, but for a more complex one there is also this: in case of the builder fns you have to document in what order the builder fns will be called (I guess in the order in which they are added). For the two stage builder the initialization order is just explicit - whatever code you write between creation of the non-listening node and the spawn.

The iroh internal protocols could be made available on the UnspawnedNode with a similar mechanism as in the other PR, so you could refer to them.

Helper to add the default iroh protocols in case you are also adding
custom protocols.
@rklaehn rklaehn force-pushed the custom-protocol-2 branch from 3280cd0 to 37f096a Compare June 17, 2024 10:34
@rklaehn
Copy link
Contributor Author

rklaehn commented Jun 17, 2024

Looks like we can change the ALPN set once the endpoint is created. With that, we get:

#[tokio::main]
async fn main() -> Result<()> {
    setup_logging();
    let args = Cli::parse();
    let node = iroh::node::Node::memory()
        .build();
    let proto = ExampleProto::build(&node);
    node
        .add_handler(EXAMPLE_ALPN, proto))
        .spawn()
        .await?;

and can remove the duplicate use of the ALPN parameter.

@rklaehn
Copy link
Contributor Author

rklaehn commented Jun 19, 2024

Folded into #2358

@rklaehn rklaehn closed this Jun 19, 2024
@rklaehn rklaehn deleted the custom-protocol-2 branch November 20, 2024 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

1 participant