-
Notifications
You must be signed in to change notification settings - Fork 125
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
state: move instantiation into State::from_request #526
Conversation
The clippy errors that are failing in CI look to be pre-existing here |
Codecov Report
@@ Coverage Diff @@
## master #526 +/- ##
==========================================
- Coverage 85.54% 85.00% -0.54%
==========================================
Files 109 110 +1
Lines 5577 5617 +40
==========================================
+ Hits 4771 4775 +4
- Misses 806 842 +36
Continue to review full report at Codecov.
|
Thanks for the PR! I'm not sure I like everyone being able to create instances of If I understand your use case correctly, you want to call a gotham handler from a raw hyper response and not use gotham to interface with hyper. This should be possible if you changed your handlers to take mutable references to the state, and converted the And don't worry about the clippy errors, that check is marked optional but GitHub doesn't really display that anywhere. |
Not quite — let me rephrase. I have a https://github.com/gotham-rs/gotham/blob/master/gotham/src/handler/mod.rs#L167 That method doesn't really take a Here's what my code looks like. This might help: impl<H: Handler + Clone + Send + Sync + 'static + RefUnwindSafe> MononokeHttpHandlerAsService<H> {
pub async fn call_gotham(self, req: Request<Body>) -> Response<Body> {
let mut state = State::from_request(req, self.addr);
if let Some(tls_socket_data) = self.tls_socket_data {
tls_socket_data.populate_state(&mut state);
}
let res = match self.handler.handle(state).await {
Ok((_state, res)) => res,
Err((state, err)) => err.into_response(&state),
};
res
}
}
// This just a little bridge to Hyper for places where we want to use this directly in `serve_connection`.
impl<H: Handler + Clone + Send + Sync + 'static + RefUnwindSafe> Service<Request<Body>>
for MononokeHttpHandlerAsService<H>
{
type Response = Response<Body>;
type Error = anyhow::Error;
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll<Result<(), Self::Error>> {
task::Poll::Ready(Ok(()))
}
fn call(&mut self, req: Request<Body>) -> Self::Future {
let this = self.clone();
async move {
let res = this.call_gotham(req).await;
Ok(res)
}
.boxed()
}
} ( Can you share a little more about the reasons behind the objection to have an owned state exposed to the client? Thanks! |
Ok I think I understand what you're trying to acchieve - still I think my suggestion would work, you'd just have to define your own trait for a handler that takes As to not allowing users to create an owned version of |
But then I can't use a Gotham Router as my handler ... so I'm not using Gotham anymore? Am I missing something? |
Oh yeah you're right that won't work ... what you're trying seems related to #183, right? I have never had this problem before so I'm not sure what the best way to solve this is. Having I'm just trying to keep the api straight-forward, and returning |
Yes, pretty much. I think one alternative here is to have Gotham pass through Extensions and make the "connect" mechanism a public interface, then I can take inject the extra state I have from Extensions into the Gotham state early in my middleware stack (this is what I mentioned on your other PR where I suggested maybe we shouldn't pull out just the OnUpgrade from extensions). To avoid making the Connected variant public, and address the use case in #183, Gotham could have 2 hyper::Service implementations. The "connected" one can just inject the client address into extensions (and stay private), and the "not connected" one can just take them from Extensions, then callers can then add their own client address into extensions. Gotham might have to tolerate the client address being missing though. Thoughts? Would you be more amenable to that kind of patch? |
No I think exposing Regarding the code, could you add a small example (similar to the one you gave above) that demonstrates how to use gotham with a custom service? Also, please move the |
I have no objections at all, though at least as far as I'm concerned I'm not really planning to use it (we configure all our services to abort on panics). I'm happy to fold this into this change.
Yeah, no problem, I'll update the PR with this. Thanks! |
52e3fe6
to
153a7bd
Compare
I updated the PR with an example and moved the code around. Let me know if I should also make the trap handler public and perhaps use it in the example. Thanks! :) |
153a7bd
to
d1ec90b
Compare
Yes, please do. This should make the example service behave exactly as the gotham provided service, thus should be a good starting point for everyone that needs to customize their service. |
This refactors the service implementation a little bit to instantiate the State via a dedicated method. The underlying goal is to allow users to use Gotham without having to use its handler. The motivation for that is to allow: - Not requiring handlers to be unwind safe. - Injecting extra things into the state that came from the socket (besides the client address), such as client TLS certificates.
d1ec90b
to
9211322
Compare
Cool; I updated the PR to use |
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.
Thanks
@msrd0 :do you think we could get a release with those changes at some point? I'd love to get us off of our fork :) |
I'm currently waiting on #468, after that I'll get a release out. |
FYI: I just released version 0.6.0 |
This refactors the service implementation a little bit to instantiate
the State via a dedicated method. The underlying goal is to allow users
to use Gotham without having to use its handler.
The motivation for this is to let users inject more things into their
state and call their handler directly instead of having to go through a
Hyper service. In our case, we use this for: