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

feat(server): allow custom implementations of listener #1217

Merged
merged 4 commits into from
Mar 4, 2025

Conversation

joelwurtz
Copy link
Contributor

Ref #1190

See this comment : #1190 (comment)

This allow end user to create its own listener as long as it returns a xitca_io::net::stream

I did not make stream generic (could be in the future) neither.

Compared to the comment i choose to not make the Listen type generic, it could be in the future with another PR

In draft for the moment as i want to test this change on my project to be sure that i achieve what i want (getting back listener after shutdown)

@joelwurtz joelwurtz marked this pull request as ready for review February 28, 2025 14:06
@joelwurtz
Copy link
Contributor Author

Passing this as ready for review, i can confirm that this is enough for a first implementation of having its custom listener.

With this i'm able to retain listener after server stop and forward them to another process

#1218 is also required to do that on quic socket

@fakeshadow
Copy link
Collaborator

fakeshadow commented Mar 1, 2025

I don't think we need both Listen and ListenDyn here. As there is no additional abstraction on top of the trait for zero cost async trait methods. Remove Listen and rename listenDyn would be sufficient.

Also Arc<Box<dyn Listen>> is double indirection and we can just use Arc<dyn Listen> instead. This would reduce some memory overhead.

Also if dyn Listen is gonna be used anyway we can remove Listener enum and implement the trait on all it's variants types directly.

@joelwurtz
Copy link
Contributor Author

If we keep only ListenDyn instead of both it means that we will have to write something like this :

impl Listen for Listener {
    fn accept(&self) -> Pin<Box<dyn Future<Output = io::Result<Stream>> + Send + '_>> {
        Box::pin(async move {

instead of

impl Listen for Listener {
    async fn accept(&self) -> io::Result<Stream> {

Or maybe i'm missing something ? (just find it clearer and consistent to be able to write async trait directly like other trait in xitca)

Will add the changes about Arc and listeners

@fakeshadow
Copy link
Collaborator

The main problem here is we don't want to expose these types to users and cause possible confusion. Take ListenObj for example it may make users wonder what ListenDyn is or even what Arc. That said it also make sense as stuff like Pin/Box/Future can also be source of confusion. So there is maybe other alternatives we can look into.

I imagine we can do the following to hide ListenDyn trait from user and keep the public traits and types to minimal:

pub trait IntoListener {
    // add an associate type for listener
    type Listener: Listen

    fn into_lisenter(self) -> io::Result<Self::Listener>;
}

pub trait Listen: Send + Sync {
 ...
}

// hide ListenDyn trait from public
#[doc(hidden)]
pub trait ListenDyn {
    ...
}

type ListenerFn = Box<dyn FnOnce() -> io::Result<Arc<dyn ListenerDyn>> + Send>;

// cast listener object inside crate so neither Arc nor ListenDyn is visiable from public api
Box::new(|| listener.into_listener().map(Arc::new))

@joelwurtz joelwurtz force-pushed the feat/generic-listener branch from e97cb51 to e1b73f6 Compare March 3, 2025 17:02
@joelwurtz joelwurtz force-pushed the feat/generic-listener branch from e1b73f6 to a6bb641 Compare March 3, 2025 17:03
@joelwurtz
Copy link
Contributor Author

Should be better with last commit then

@fakeshadow
Copy link
Collaborator

I believe we can remove the Listen impl for Box<impl ListenDyn> as we only use ListenDyn internally. Otherwise its good.

@joelwurtz
Copy link
Contributor Author

Done

@fakeshadow
Copy link
Collaborator

Thanks the PR is good. I'll resolve the CI issue separately.

@fakeshadow fakeshadow merged commit cab9658 into HFQR:main Mar 4, 2025
1 of 13 checks passed
@joelwurtz joelwurtz deleted the feat/generic-listener branch March 4, 2025 17:16
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.

2 participants