|
@@ -1,16 +1,10 @@
|
|
-extern crate futures;
|
|
|
|
-extern crate hyper;
|
|
|
|
-extern crate net2;
|
|
|
|
-extern crate tokio_core;
|
|
|
|
-extern crate tokio_postgres;
|
|
|
|
-
|
|
|
|
use std::fmt::Write;
|
|
use std::fmt::Write;
|
|
-use std::net::ToSocketAddrs;
|
|
|
|
|
|
+use std::sync::Arc;
|
|
|
|
|
|
-use futures::{future, Future};
|
|
|
|
use hyper::header::{HeaderValue, CONTENT_TYPE, SERVER};
|
|
use hyper::header::{HeaderValue, CONTENT_TYPE, SERVER};
|
|
use hyper::service::service_fn;
|
|
use hyper::service::service_fn;
|
|
use hyper::{Body, Response};
|
|
use hyper::{Body, Response};
|
|
|
|
+use std::net::ToSocketAddrs;
|
|
|
|
|
|
mod db;
|
|
mod db;
|
|
mod server;
|
|
mod server;
|
|
@@ -22,7 +16,6 @@ fn main() {
|
|
.user("benchmarkdbuser")
|
|
.user("benchmarkdbuser")
|
|
.password("benchmarkdbpass")
|
|
.password("benchmarkdbpass")
|
|
.dbname("hello_world");
|
|
.dbname("hello_world");
|
|
-
|
|
|
|
let psql_addr = ("tfb-database", 5432)
|
|
let psql_addr = ("tfb-database", 5432)
|
|
.to_socket_addrs()
|
|
.to_socket_addrs()
|
|
.expect("must be able to resolve database hostname")
|
|
.expect("must be able to resolve database hostname")
|
|
@@ -35,17 +28,26 @@ fn main() {
|
|
|
|
|
|
let html_ct = HeaderValue::from_static("text/html; charset=utf-8");
|
|
let html_ct = HeaderValue::from_static("text/html; charset=utf-8");
|
|
let server_header = HeaderValue::from_static("hyper");
|
|
let server_header = HeaderValue::from_static("hyper");
|
|
|
|
+ let config = psql_config.clone();
|
|
|
|
|
|
// Before handling any requests, we should grab a DB connection.
|
|
// Before handling any requests, we should grab a DB connection.
|
|
- let db_fut =
|
|
|
|
- db::connect(psql_addr, psql_config.clone(), handle.clone()).map(move |mut db_conn| {
|
|
|
|
|
|
+ let db_fut = async move {
|
|
|
|
+ let handle = handle2.clone();
|
|
|
|
+ let db_conn = db::connect(psql_addr, config, handle).await?;
|
|
|
|
+ let db_conn = Arc::new(db_conn);
|
|
|
|
+
|
|
|
|
+ let html_ct = html_ct.clone();
|
|
|
|
+ let server_header = server_header.clone();
|
|
|
|
+
|
|
|
|
+ // This is the `Service` that will handle the connection.
|
|
|
|
+ // `service_fn` is a helper to convert a function that
|
|
|
|
+ // returns a Future<Item=Response> into a `Service`.
|
|
|
|
+ let svc = service_fn(move |req| {
|
|
let html_ct = html_ct.clone();
|
|
let html_ct = html_ct.clone();
|
|
let server_header = server_header.clone();
|
|
let server_header = server_header.clone();
|
|
|
|
+ let db_conn = db_conn.clone();
|
|
|
|
|
|
- // This is the `Service` that will handle the connection.
|
|
|
|
- // `service_fn` is a helper to convert a function that
|
|
|
|
- // returns a Future<Item=Response> into a `Service`.
|
|
|
|
- let svc = service_fn(move |req| {
|
|
|
|
|
|
+ async move {
|
|
let (req, _body) = req.into_parts();
|
|
let (req, _body) = req.into_parts();
|
|
// For speed, reuse the allocated header map from the request,
|
|
// For speed, reuse the allocated header map from the request,
|
|
// instead of allocating a new one. Because.
|
|
// instead of allocating a new one. Because.
|
|
@@ -57,30 +59,30 @@ fn main() {
|
|
|
|
|
|
match req.uri.path() {
|
|
match req.uri.path() {
|
|
"/fortunes" => {
|
|
"/fortunes" => {
|
|
- future::Either::A(db_conn.tell_fortune().map(move |fortunes| {
|
|
|
|
- let mut buf = String::with_capacity(2048);
|
|
|
|
- let _ = write!(&mut buf, "{}", FortunesTemplate { fortunes });
|
|
|
|
- let mut res = Response::new(Body::from(buf));
|
|
|
|
- *res.headers_mut() = headers;
|
|
|
|
- res
|
|
|
|
- }))
|
|
|
|
|
|
+ let fortunes = db_conn.tell_fortune().await?;
|
|
|
|
+ let mut buf = String::with_capacity(2048);
|
|
|
|
+ let _ = write!(&mut buf, "{}", FortunesTemplate { fortunes });
|
|
|
|
+ let mut res = Response::new(Body::from(buf));
|
|
|
|
+ *res.headers_mut() = headers;
|
|
|
|
+ Ok::<_, Box<dyn std::error::Error + Send + Sync>>(res)
|
|
}
|
|
}
|
|
_ => {
|
|
_ => {
|
|
let mut res = Response::new(Body::empty());
|
|
let mut res = Response::new(Body::empty());
|
|
*res.status_mut() = hyper::StatusCode::NOT_FOUND;
|
|
*res.status_mut() = hyper::StatusCode::NOT_FOUND;
|
|
*res.headers_mut() = headers;
|
|
*res.headers_mut() = headers;
|
|
- future::Either::B(future::ok(res))
|
|
|
|
|
|
+ Ok(res)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- });
|
|
|
|
-
|
|
|
|
- // Spawn the `serve_connection` future into the runtime.
|
|
|
|
- handle2.spawn(
|
|
|
|
- http.serve_connection(socket, svc)
|
|
|
|
- .map_err(|e| eprintln!("connection error: {}", e)),
|
|
|
|
- );
|
|
|
|
|
|
+ }
|
|
});
|
|
});
|
|
- handle.spawn(db_fut);
|
|
|
|
|
|
+ // Spawn the `serve_connection` future into the runtime.
|
|
|
|
+ handle2.spawn(http.serve_connection(socket, svc));
|
|
|
|
+ Ok::<_, Box<dyn std::error::Error>>(())
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ handle.spawn(async move {
|
|
|
|
+ let _ = db_fut.await;
|
|
|
|
+ });
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|