Hello!
I need to make a single application that embeds 2 web servers (different ports, different endpoints, different handlers) plus some glue logic.
I managed to put this together in a flat file (compiles and works as expected):
// [package]
// name = "multi_server"
// version = "1.0.0"
// edition = "2018"
//
// [dependencies]
// axum = "0.1"
// tokio = { version = "1.9", features = ["full"] }
// hyper = { version = "0.14", features = ["full"] }
use axum::prelude::*;
use hyper;
async fn root1() -> &'static str {
"Hello, World from server 1!"
}
async fn root2() -> &'static str {
"Hello, World from server 2!"
}
#[tokio::main]
async fn main() -> Result<(), hyper::Error> {
let app1 = route("/", get(root1));
let server1 =
hyper::Server::bind(&"0.0.0.0:3000".parse().unwrap()).serve(app1.into_make_service());
let app2 = route("/", get(root2));
let server2 =
hyper::Server::bind(&"0.0.0.0:3001".parse().unwrap()).serve(app2.into_make_service());
let (r1, r2) = tokio::join!(server1, server2);
r1.and(r2).and(Ok(()))
}
Thing I'm trying and I lost most of today is: how to put each server in a submodule and build them with module-local function:
// [package]
// name = "multi_server"
// version = "1.0.0"
// edition = "2018"
//
// [dependencies]
// axum = "0.1"
// tokio = { version = "1.9", features = ["full"] }
// hyper = { version = "0.14", features = ["full"] }
use axum::prelude::*;
use hyper;
mod s1 {
async fn root() -> &'static str {
"Hello, World from server 1!"
}
pub async fn build(addr: &str) -> WTF_PUT_HERE {
use axum::prelude::*;
let app = route("/", get(root));
hyper::Server::bind(&addr.parse().unwrap()).serve(app.into_make_service())
}
// OR
pub async fn app() -> WTF_PUT_HERE {
use axum::prelude::*;
route("/", get(root))
}
}
mod s2 {
async fn root() -> &'static str {
"Hello, World from server 2!"
}
pub async fn build(addr: &str) -> WTF_PUT_HERE {
use axum::prelude::*;
let app = route("/", get(root));
hyper::Server::bind(&addr.parse().unwrap()).serve(app.into_make_service())
}
// OR
pub async fn app() -> WTF_PUT_HERE {
use axum::prelude::*;
route("/", get(root))
}
}
#[tokio::main]
async fn main() -> Result<(), hyper::Error> {
let server1 = s1::build("0.0.0.0:3000");
let server2 = s1::build("0.0.0.0:3001");
// OR (at least)
let server1 = hyper::Server::bind("0.0.0.0:3000".parse().unwrap()).serve(s1::app().into_make_service());
let server2 = hyper::Server::bind("0.0.0.0:3001".parse().unwrap()).serve(s2::app().into_make_service());
let (r1, r2) = tokio::join!(server1, server2);
r1.and(r2).and(Ok(()))
}
And yes, I tried putting in the WTF_PUT_HERE
monstertypes compiler suggested, but each attempt ended with compiler telling to finger myself.
I browsed for hours through all forums, lists, docs, manuals, howtos, examples and sources. Zero. Nada. Null. References to nonexisting documents. References to outdated packages. References to alpha drafts. Metoos. References to chapters consisting of a sole TBD. Overall documentation on anything async is unfortunately worthless (sorry about that, but that's what I feel after today). It gives you a concrete example (working, after you spend good time with your crystal ball deducting the correct features
in [dependencies]
) and absolutely no clue how to sidestep even a micron.
I'm so damn close to slamming the door and going back to golang
despite all my love for Rust all in itself.