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

dylib routing issue caused by RouteId #1803

Closed
1 task done
Curid opened this issue Mar 2, 2023 · 4 comments · Fixed by #1806
Closed
1 task done

dylib routing issue caused by RouteId #1803

Curid opened this issue Mar 2, 2023 · 4 comments · Fixed by #1806
Labels
A-axum C-bug Category: This is a bug.

Comments

@Curid
Copy link

Curid commented Mar 2, 2023

  • I have looked for existing issues (including closed) about this

Bug Report

Version

├── axum v0.6.9
│ ├── axum-core v0.3.2

Platform

Linux

Description

Adding routes to a router from a shared library causes routes to point to the wrong handlers. I'm guessing this is the issue.

Route /a should respond with A instead of C

minimal example repo

main.rs

#[tokio::main]
async fn main() {
    let router = Router::new()
        .route("/a", get(|| async { "A" }))
        .route("/b", get(|| async { "B" }));

    let dylib = unsafe { Library::new("./target/debug/libdylib.so").expect("load library") };
    let add_route: Symbol<fn(router: Router) -> Router> =
        unsafe { dylib.get(b"add_route") }.expect("load symbol");

    let router = add_route(router);

    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(router.into_make_service())
        .await
        .unwrap();
}

dylib.rs

#[no_mangle]
pub fn add_route(router: Router) -> Router {
    router.route("/c", get(|| async { "C" }))
}
@davidpdrsn
Copy link
Member

I haven't really worked much with dynamic libraries but I suppose the solution would be to use a random number for the ids instead of incrementing an atomic counter. Wdyt?

@davidpdrsn davidpdrsn added C-bug Category: This is a bug. A-axum labels Mar 3, 2023
@jplatte
Copy link
Member

jplatte commented Mar 3, 2023

I would worry about introducing that kind of non-determinism. It could still lead to duplicate usage of an ID, even if very unlikely. Couldn't we just have a regular u64 inside Router that is used for the RouteId and incremented in the two places we currently use RouteId::next()?

@davidpdrsn
Copy link
Member

I used to think that wouldn't work for cases like

let one = Router::new().route("/one", ...);
let two = Router::new().route("/two", ...);

one.merge(two)

but since merge just calls route which creates a new id I actually think it should work!

@Curid
Copy link
Author

Curid commented Mar 3, 2023

Thanks for the quick fix! I wasn't sure if this even was a supported use case, since core Tokio has a few similar issues that can't really be fixed without breaking changes.

tokio-rs/tokio#4940

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-axum C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants