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

Refactor TransportCallbacks interface #987

Open
akoshelev opened this issue Mar 20, 2024 · 0 comments
Open

Refactor TransportCallbacks interface #987

akoshelev opened this issue Mar 20, 2024 · 0 comments

Comments

@akoshelev
Copy link
Collaborator

          We discussed it offline and agreed that `TransportCallbacks` needs to go away. A better interface for handlers would be similar to [this one](https://docs.rs/iron/latest/iron/middleware/trait.Handler.html). 

It is still worth to encapsulate the delivery method inside Transport interface, so messages delivered via HTTP or potentially CF workers channel have the same structure when handled by application logic. We may have a good abstraction for it already - Addr struct used inside in-memory network.

So our handler interface may look like this

trait Handler<I: TransportIdentity> {
   fn handle(&self, _: &Addr<I>) -> Result<Response>
}

HTTP transport can parse HTTP requests into Addr struct and application will have a unified logic to process requests based on Addr:RouteId field

Originally posted by @akoshelev in #982 (comment)

akoshelev added a commit to akoshelev/raw-ipa that referenced this issue Mar 25, 2024
See private-attribution#987 for motivation. I had to decide whether I want to use dynamic
dispatch vs clunky HTTP interfaces with another generic parameter propagated
through the entire stack. I don't have a conslusive answer which way is better,
both have significant downsides.

Problems with DD approach that is proposed in this change:

* Hard to keep `RequestHandler` trait object safe. No generics for `handle` method,
use of `async_trait` etc. That removes the opportunity for some optimizations, namely
using a trait to pass data down to the handler. It could be better if HTTP layer just
passes the same structs it gets from HTTP layer without an extra conversion that must occur
if dynamic dispatch is used.
* Non zero-cost abstraction. To get data back from the handler, we have to use the
same format, right now it is JSON but I doubt we can do better than binary serialization,
which means more work to get the data out.
* `Box<dyn Trait<....` is everywhere now.

Problems with static dispatch (I will link a commit) is more code that requires a change.
It is also not clear whether we can make it a zero-cost abstraction.

It is mentioned in private-attribution#987 but I will reiterate it here that the reason for the intermediate layer
data representation (betweeen HTTP and transport) is to support various delivery channels for IPA,
that could potentially include something like CF workers. We don't seem to have an opportunity
to rely on our network layer being HTTP in the long term.
akoshelev added a commit that referenced this issue Apr 5, 2024
)

* Delete `TransportCallbacks` and use `RequestHandler` trait instead

See #987 for motivation. I had to decide whether I want to use dynamic
dispatch vs clunky HTTP interfaces with another generic parameter propagated
through the entire stack. I don't have a conslusive answer which way is better,
both have significant downsides.

Problems with DD approach that is proposed in this change:

* Hard to keep `RequestHandler` trait object safe. No generics for `handle` method,
use of `async_trait` etc. That removes the opportunity for some optimizations, namely
using a trait to pass data down to the handler. It could be better if HTTP layer just
passes the same structs it gets from HTTP layer without an extra conversion that must occur
if dynamic dispatch is used.
* Non zero-cost abstraction. To get data back from the handler, we have to use the
same format, right now it is JSON but I doubt we can do better than binary serialization,
which means more work to get the data out.
* `Box<dyn Trait<....` is everywhere now.

Problems with static dispatch (I will link a commit) is more code that requires a change.
It is also not clear whether we can make it a zero-cost abstraction.

It is mentioned in #987 but I will reiterate it here that the reason for the intermediate layer
data representation (betweeen HTTP and transport) is to support various delivery channels for IPA,
that could potentially include something like CF workers. We don't seem to have an opportunity
to rely on our network layer being HTTP in the long term.

* Fix the memory leak inside TestApp

* Fix one FIXME

* Clean up code

* Feedback
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

No branches or pull requests

1 participant