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>;