From 15afbd1e53e9d08c83c94011d34688c2a43fdd22 Mon Sep 17 00:00:00 2001 From: pavlospt Date: Sun, 31 Mar 2024 23:29:57 +0300 Subject: [PATCH] Introduce shuttle-ntex service --- .circleci/config.yml | 2 ++ services/shuttle-ntex/Cargo.toml | 17 ++++++++++++++ services/shuttle-ntex/README.md | 22 ++++++++++++++++++ services/shuttle-ntex/src/lib.rs | 40 ++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) create mode 100644 services/shuttle-ntex/Cargo.toml create mode 100644 services/shuttle-ntex/README.md create mode 100644 services/shuttle-ntex/src/lib.rs diff --git a/.circleci/config.yml b/.circleci/config.yml index a9bed31f93..e78bff55a3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -620,6 +620,7 @@ workflows: - resources/opendal - services/shuttle-actix-web - services/shuttle-axum + - services/shuttle-ntex - services/shuttle-poem - services/shuttle-rocket - services/shuttle-salvo @@ -893,6 +894,7 @@ workflows: path: - services/shuttle-actix-web - services/shuttle-axum + - services/shuttle-ntex - services/shuttle-poem - services/shuttle-rocket - services/shuttle-salvo diff --git a/services/shuttle-ntex/Cargo.toml b/services/shuttle-ntex/Cargo.toml new file mode 100644 index 0000000000..b6ee119f24 --- /dev/null +++ b/services/shuttle-ntex/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "shuttle-ntex" +version = "0.1.0" +edition = "2021" +license = "Apache-2.0" +description = "Service implementation to run a Ntex webserver on shuttle" +keywords = ["shuttle-service", "ntex"] + +[workspace] + +[dependencies] +ntex = { version = "1.2.1"} +shuttle-runtime = { path = "../../runtime", version = "0.42.0", default-features = false } +num_cpus = "1.16.0" + +[dev-dependencies] +tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread"] } diff --git a/services/shuttle-ntex/README.md b/services/shuttle-ntex/README.md new file mode 100644 index 0000000000..0607f77c5d --- /dev/null +++ b/services/shuttle-ntex/README.md @@ -0,0 +1,22 @@ +## Shuttle service integration for the Ntex Web framework + +### Example + +```rust +use ntex::web::{get, ServiceConfig}; +use shuttle_ntex::ShuttleNtexWeb; + +#[get("/")] +async fn hello_world() -> &'static str { + "Hello World!" +} + +#[shuttle_runtime::main] +async fn ntex_web() -> ShuttleNtexWeb { + let config = move |cfg: &mut ServiceConfig| { + cfg.service(hello_world); + }; + + Ok(config.into()) +} +``` diff --git a/services/shuttle-ntex/src/lib.rs b/services/shuttle-ntex/src/lib.rs new file mode 100644 index 0000000000..b0ecc313ab --- /dev/null +++ b/services/shuttle-ntex/src/lib.rs @@ -0,0 +1,40 @@ +#![doc = include_str!("../README.md")] +use std::net::SocketAddr; + +/// A wrapper type for a closure that returns an [ntex::web::ServiceConfig] so we can implement +/// [shuttle_runtime::Service] for it. +#[derive(Clone)] +pub struct NtexWebService(pub F); + +#[shuttle_runtime::async_trait] +impl shuttle_runtime::Service for NtexWebService +where + F: FnOnce(&mut ntex::web::ServiceConfig) + Send + Clone + 'static, +{ + async fn bind(mut self, addr: SocketAddr) -> Result<(), shuttle_runtime::Error> { + // Start a worker for each cpu, but no more than 4. + let worker_count = num_cpus::get().min(4); + + let server = + ntex::web::HttpServer::new(move || ntex::web::App::new().configure(self.0.clone())) + .workers(worker_count) + .bind(addr)? + .run(); + + server.await.map_err(shuttle_runtime::CustomError::new)?; + + Ok(()) + } +} + +impl From for NtexWebService +where + F: FnOnce(&mut ntex::web::ServiceConfig) + Send + Clone + 'static, +{ + fn from(service_config: F) -> Self { + Self(service_config) + } +} + +#[doc = include_str!("../README.md")] +pub type ShuttleNtexWeb = Result, shuttle_runtime::Error>;