#feat(service): add adapter for tower ser...

39 messages · Page 1 of 1 (latest)

tribal ridge
cedar mist

I really just want hyper_util::Server::bind(addr).serve(axum_router.into_make_service()).await

thats familiar to people and makes it easy to get started

and then also hyper_util::Server::bind(addr).configure_something(...).serve(...)

then tonic users could use the same server

currently you have you make your own TcpListener, loop to accept connections, spawn tasks, and all that

tribal ridge

yeah sure that can work as well. Would you label that also under legacy or would that be just the ok thing to do. Hinting at the existing client legacy thing.

Is there already an issue about this or shall I create this? So I can start to work on that this week then. Next to the PR reviews. Or shall I not do those for now? Given you or someone else anyway still needs to review them yourself 😅

cedar mist

yeah sure that can work as well. Would you label that also under legacy or would that be just the ok thing to do. Hinting at the existing client legacy thing.
I don't mind either way. Not really use what the legacy module is for. Does it mean things will be rewritten? I suppose the Client one works just fine

not sure if there is an issue for it

tribal ridge

Ok given that that is a Hyper thing I guess @lunar lagoon can also chip in this week to see what he thinks of it and if that's useful for me to contribute.

My intention is just to become a contributor of both tower and hyper, with the little time I have, as both projects are very central to my own project rama, so I have all interests to help towards the future of these projects.

cedar mist

we have definitely talked about it before. Just one has done anything yet 😛

tribal ridge

Fair enough, then I guess I'll just get around doing it. Once I start on it I'll create an issue if one doesn't exit yet or else I'll put in the existing one that I'm starting on it.

Also I know I come a bit out of the blue after all these years, so if you want me to ever formally introduce myself to you and the other maintainers, do let me know. Or perhaps that is more for a time much later after I've actually done stuff 🙂

Btw as you already have a PR. Do you want me to continue that one (and how you prefer that).

Or given that you want to change gears I could also start a new PR “fresh”.

cedar mist

I'd say start a new one. I kinda wanna close my PR and maybe do some more testing myself

but right now my focus is on getting tower-http and axum out the door

tribal ridge

So also tower 0.5 or is that independent?

cedar mist

thats independent

we do need to ship that at some point as well though

tribal ridge

You need help with tower-http?

cedar mist

always 🙂 although since you seem interested in tricky type system things and given your other work I think maybe the most pressing thing is thinking about a design for the next version of tower-service. Now that async fn and impl Trait in traits are going to stable.

Lucio (from tonic) said he was gonna do some thinking but don't think he ever got around to it

lots of people have posted thoughts in various issues I don't think any one has actually made a real proposal and tried to port some code

things like do we keep poll_ready, do we use async fn call, do we use gats (so you can return a future that borrows self), and those kinds of things

tribal ridge

Well I would invite you and others to take a good look at tower-async. It's a direct port of tower and tower-http for exactly that purpose. So someone did definetely make a real proposal and port some code. Me. And I am in fact even using it in production.

  • In the FAQ of its readme you can read why I removed poll_ready and some related functionality
  • I implement it as a return impl Trait. You can see it in the tower-async-service crate. When implementing middleware services you can still use async fn but the public traits are using impl Future
  • I also from 0.1 to 0.2 , just these last days switched to &self instead of &mut self, as I never had a real need for the mutability and it makes interfacing with things like hyper 1 much easier

These are all just proposals though. I am open to any feedback, a totally different direction. I can do more experimentation if you want a different direction (completely or partly). Honestly fully open about it all. I just already needed it as for my purposes (where I do deal with plenty of async fn usage in my middlewares it was becoming a pain in the ass to hand roll these futures myself. If everything in Rust was manual futures it would be a lot easier, and I don't mind the work. But given that some stuff (e.g. plenty of tokio utility code) works with async fn that became very awkward and painful very soon.

So yeah I would suggest take that perhaps as a starting point between you all for discussions, involving me or not. And then we can perhaps take it from there?

cedar mist

I think maybe opening an issue on tower (or maybe there already is one) and present your learnings there and get feedback from tower maintainers

fwiw I think exactly what your Service trait looks like is what I'd like to see 🙂

tribal ridge

all those crates can be run with stable very soon. Only exception is tower-async-bridge and tower-async-hyper. The bridge one is of no importance as we wouldn't need it, given that is meant to bridge with tower, which we wouldn't need.

tower-async-hyper we also wouldn't need but we would need to be able to use tower via hyper-util. And what I learned from there is that while to use the tower-async crates directly and implement your stuff, you do indeed not need to use nightly Rust soon. But as long as things like Hyper do not work with async fn traits in some way, then there's a need for boxing as far as I can see (and what I did) and that can for now only be done with nightly Rust probably until somewhere in 2024, as you need to be able to use the call(): Send syntax for that.

That said, if we would put this kind of design into tower itself then of course we can make use of that directly in hyper-util and we would be able to facilitate that without having to boxing, so all is then good again I guess.

So yeah thinking it through the current design can probably be used for stable Rust this year.

That's the good news. But the tricky news is that I did make a lot of heavy decisions, some or all of which maintainers might not agree with, Which I am fine with, but depending how much changes need to be made that would delay that timing on which I can deliver further.

I'll open an issue then in tower-rs/tower tonight. Currently I Can only type fast messages as my youngest (1 year old) is crawling over my legs all the time 😅

And you and the maintainers can take it from there.

As I said I'm open to anything.

tower-async is not meant to be permanent or me wanting it this way or no way. It was just unblock myself. A realization made in the 900th iteration of Rama 🥲 After struggling a lot with classic tower in many iterations before that.

classic tower works fine for my regular backend work, but for my proxy stuff it wasn't working well. And I really need to get rid of my giant Go code base as I'm seriously blocked there. (Working on a privately forked version of Golang since years, don't ask, it's a mess that ecosystem >.<).

cedar mist

I think its awesome that you actually ported so much! Its really valuable to know that most things actually can be ported to this design 😅

tribal ridge

Yeah I was plesently surprised as well. Rabbit holes don't end up that often in such a bright place, but with tower-async I did get to a place where I'm actually using it. And since hyper 1 that somehow only became easier as the low level stuff works good for me. But I guess not so fun for regular backend work.

cedar mist

I suppose the hardest ones are things like balance, which uses poll_ready

maybe buffer as well 🤔

tribal ridge

Yeah those I removed in my current version. As I also don’t have a need for it. For me that all falls in the realm of scaling and distributing which I find more natural to solve horizontally with load balancers and the like, keeping my individual processes small in footprint

Of course that is just my point of view. I’m happy to lead the development on this with a design that you all agree on. If that includes stuff like that I’m ok with including that as well 🙂

That said you can also still work on a future level in this new design

And poll ready like logic can just be done as part of your call where you want it. So I did think about that design and have vague ideas how to do it. But as I don’t have a need or desire for it I didn’t do it.

My original background is the games industry (r&d and game engines) btw 🙂 but left it about 6 years ago. So as an ex c++ junky I do appreciate Rust :’)

cedar mist

hehe I work at embark studios so mostly just do game dev. Haven't worked on web things during my job for a while now