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

Add handler for unknown method #405

Merged
merged 10 commits into from
Jan 5, 2023
Merged

Add handler for unknown method #405

merged 10 commits into from
Jan 5, 2023

Conversation

hspaay
Copy link
Contributor

@hspaay hspaay commented Dec 28, 2022

This is a proposed solution to be able to customize the handling of unknown methods. The default behavior is unchanged but a hook allows customized behavior.

The hook can be used to dynamically create a method and have it invoked as if it existed all along.
I was able to use this in a proxy service that dynamically obtains capabilities/methods from other services and forwards requests to those services.

@hspaay
Copy link
Contributor Author

hspaay commented Dec 29, 2022

This is as barebones as it gets. Lets start picking at it. Interface? yes/no/good enough anyone? :)

@hspaay hspaay marked this pull request as ready for review December 29, 2022 18:43
lthibault
lthibault previously approved these changes Dec 29, 2022
Copy link
Collaborator

@lthibault lthibault left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@zenhack
Copy link
Contributor

zenhack commented Dec 29, 2022

Could use a test, but I'm fine with this. Before we tag 3.0 I think I want to do the interface reworking we talked about though.

@lthibault
Copy link
Collaborator

Ah yeah, +1 to the test.

Also, @zenhack, can you open an issue for the interface refactor? I think you're in the best position to accurately spec it out.

@lthibault lthibault changed the title 400: Add handler for unknown method - draft Add handler for unknown method Dec 29, 2022
server/server_test.go Outdated Show resolved Hide resolved
server/server_test.go Outdated Show resolved Hide resolved
server/server_test.go Outdated Show resolved Hide resolved
@lthibault
Copy link
Collaborator

I've flagged some minor things, but this basically LGTM. I think we're good to merge after these fixes.

lthibault
lthibault previously approved these changes Jan 2, 2023
Copy link
Collaborator

@lthibault lthibault left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Copy link
Contributor

@zenhack zenhack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor thing

return &sm
}
blankBoot := capnp.NewClient(srv)
lis, err := net.Listen("tcp", ":0")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can simplify this and entirely skip setting up a connection with something on the other side and just use blankBoot in place of blankClient

Copy link
Contributor Author

@hspaay hspaay Jan 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zenhack wouldn't that invoke 'Send' instead of 'Recv'? The hook was intended for acting as a proxy forwarder and it doesn't exist in Send.
I do wonder about the use-case for sending on blankBoot directly. I've seen this in other testcases and tried it out only to find it doesn't invoke Recv. When is this workflow applicable? It looks to be intended for the client side?
In the use-case I have, the client side uses the actual client for the intended method in order to build the proper message. It is send to the gateway/proxy which looks up the service that implements that method and forwards it. This allows intercepting the message and do some middleware stuff like authentication and logging, and of course forwarding to the actual capability provider. It works like a charm!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O.O can't believe I missed this on my first look: Yeah, it would, and you really don't want the two to have different behavior -- the only difference that's supposed to be there is who allocates the arguments. Probably we should move the logic for method lookup into Server.start so it's not duplicated in both Send and Recv.

Copy link
Contributor Author

@hspaay hspaay Jan 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it looks like there is some room for cleanup here as well. Combine methods.find, although that might not be as easy as it sounds.
{rant} Looking at the Send() function the return statement is rather confusing. I tried reading it a few times and am still not quite sure what is happening in what order. I've been bitten in the past by statements that do more than one thing. In this case the return statement of Send() is akin to a rattlesnake den. The casual reader will benefit from having it split into a statement for each of the things it is doing. It looks like it needs the result of methods.find before srv.start is called but this is not quite clear to me.

Would it be okay if I add the hook to Send() in the same way it is added to Recv and leave the cleanup to more capable folks? I'd rather leave the test case as is to make sure the hook is tested with Recv, since the primary use-case is forwarding the request on receive.

@zenhack
Copy link
Contributor

zenhack commented Jan 3, 2023 via email

@hspaay
Copy link
Contributor Author

hspaay commented Jan 3, 2023

I'd be ok with that; I won't force you to shave that yak.

Thank you.

@zenhack
Copy link
Contributor

zenhack commented Jan 3, 2023

I'd still like to remove the connection from that test, but other than that LGTM

@lthibault lthibault merged commit 7409aa9 into capnproto:main Jan 5, 2023
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.

3 participants