Skip to content

Commit e23c591

Browse files
authored
Merge pull request #1613 from input-output-hk/actix_2_0
Upgrade Actix-web to 2.0
2 parents eeb9b11 + f14bed2 commit e23c591

File tree

8 files changed

+921
-742
lines changed

8 files changed

+921
-742
lines changed

Cargo.lock

Lines changed: 511 additions & 272 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jormungandr/Cargo.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ Midgard Serpent
1212
edition = "2018"
1313

1414
[dependencies]
15-
actix-cors = "0.1.0"
16-
actix-rt = "0.2.6"
17-
actix-threadpool = "0.1.2"
18-
actix-web = { version = "1.0.9", default-features = false, features = [ "rust-tls" ] }
15+
actix-cors = "0.2.0"
16+
actix-rt = "^1.0.0"
17+
actix-threadpool = "^0.3.1"
18+
actix-web = { version = "2.0.0", default-features = false, features = [ "rustls" ] }
1919
juniper = "0.13.1"
2020
bincode = "1.0.1"
2121
bytes = "0.4"
@@ -30,6 +30,7 @@ cardano-legacy-address = { path = "../chain-deps/cardano-legacy-address" }
3030
imhamt = { path = "../chain-deps/imhamt" }
3131
error-chain = "0.12"
3232
futures = "0.1"
33+
futures03 = { package = "futures", version = "0.3.1", features = ["compat"] }
3334
http = "0.1.16"
3435
humantime = "1.2"
3536
hyper = "0.12"
@@ -40,7 +41,7 @@ network-core = { path = "../chain-deps/network-core" }
4041
network-grpc = { path = "../chain-deps/network-grpc" }
4142
poldercast = "0.11"
4243
rand = "0.7"
43-
rustls = "0.15.2"
44+
rustls = "^0.16.0 "
4445
serde = "1.0"
4546
serde_derive = "1.0"
4647
serde_json = "1.0.38"

jormungandr/src/rest/explorer/handlers.rs

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,43 @@ use actix_web::error::{ErrorBadRequest, ErrorInternalServerError, ErrorServiceUn
33
use actix_web::web::{Data, Json};
44
use actix_web::{http, Error, HttpResponse, Responder};
55

6-
use futures::Future;
7-
86
use crate::explorer::graphql::GraphQLRequest;
97
pub use crate::rest::Context;
108

11-
macro_rules! ActixFuture {
12-
() => { impl Future<Item = impl Responder + 'static, Error = impl Into<Error> + 'static> + 'static }
13-
}
14-
15-
pub fn graphiql(_context: Data<Context>) -> impl Responder {
9+
pub async fn graphiql() -> impl Responder {
1610
let html = juniper::http::graphiql::graphiql_source("/explorer/graphql");
1711
HttpResponse::Ok()
1812
.content_type("text/html; charset=utf-8")
1913
.body(html)
2014
}
2115

22-
pub fn graphql(context: Data<Context>, data: Json<GraphQLRequest>) -> ActixFuture!() {
23-
context
24-
.try_full_fut()
25-
.and_then(|context| {
26-
context
27-
.explorer
28-
.clone()
29-
.ok_or(ErrorServiceUnavailable("Explorer not enabled"))
30-
})
31-
.and_then(move |explorer|
32-
// Run the query in a threadpool, as Juniper is synchronous
33-
actix_threadpool::run(move || {
34-
let response = data.execute(&explorer.schema, &explorer.context());
35-
match response.is_ok() {
36-
true => serde_json::to_string(&response).map(Some),
37-
false => Ok(None),
38-
}})
39-
.then(|res| match res {
40-
Ok(Some(response)) => Ok(response),
41-
Ok(None) => Err(ErrorBadRequest("Error processing query")),
42-
Err(BlockingError::Canceled) => Err(ErrorInternalServerError("Data execution cancelled")),
43-
Err(BlockingError::Error(serde_err)) => Err(ErrorInternalServerError(serde_err)),
44-
}
45-
))
46-
.map(|response| {
47-
HttpResponse::Ok()
48-
.header(http::header::CONTENT_TYPE, "application/json")
49-
.body(response)
50-
})
51-
.map_err(|err| ErrorInternalServerError(err))
16+
pub async fn graphql(
17+
context: Data<Context>,
18+
data: Json<GraphQLRequest>,
19+
) -> Result<impl Responder, Error> {
20+
let explorer = context
21+
.try_full()?
22+
.explorer
23+
.clone()
24+
.ok_or(ErrorServiceUnavailable("Explorer not enabled"))?;
25+
// Run the query in a threadpool, as Juniper is synchronous
26+
let res = actix_threadpool::run(move || {
27+
let response = data.execute(&explorer.schema, &explorer.context());
28+
match response.is_ok() {
29+
true => serde_json::to_string(&response).map(Some),
30+
false => Ok(None),
31+
}
32+
})
33+
.await;
34+
let response = match res {
35+
Ok(Some(response)) => response,
36+
Ok(None) => return Err(ErrorBadRequest("Error processing query")),
37+
Err(BlockingError::Canceled) => {
38+
return Err(ErrorInternalServerError("Data execution cancelled"))
39+
}
40+
Err(BlockingError::Error(serde_err)) => return Err(ErrorInternalServerError(serde_err)),
41+
};
42+
Ok(HttpResponse::Ok()
43+
.header(http::header::CONTENT_TYPE, "application/json")
44+
.body(response))
5245
}

jormungandr/src/rest/explorer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ use actix_web::{
77

88
pub fn service(root_path: &str) -> impl HttpServiceFactory {
99
scope(root_path)
10-
.route("/graphql", post().to_async(handlers::graphql))
10+
.route("/graphql", post().to(handlers::graphql))
1111
.route("/graphiql", get().to(handlers::graphiql))
1212
}

jormungandr/src/rest/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ pub use self::server::{Error, Server, ServerStopper};
1010
use actix_web::error::{Error as ActixError, ErrorInternalServerError, ErrorServiceUnavailable};
1111
use actix_web::web::ServiceConfig;
1212

13-
use futures::{Future, IntoFuture};
1413
use slog::Logger;
1514
use std::sync::{Arc, RwLock};
1615

@@ -49,10 +48,6 @@ impl Context {
4948
*self.full.write().expect("Context state poisoned") = Some(Arc::new(full_context));
5049
}
5150

52-
pub fn try_full_fut(&self) -> impl Future<Item = Arc<FullContext>, Error = ActixError> {
53-
self.try_full().into_future()
54-
}
55-
5651
pub fn try_full(&self) -> Result<Arc<FullContext>, ActixError> {
5752
self.full
5853
.read()

jormungandr/src/rest/server/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod error;
66
pub use self::error::Error;
77

88
use crate::settings::start::{Cors as CorsConfig, Rest, Tls as TlsConfig};
9-
use actix_cors::Cors;
9+
use actix_cors::{Cors, CorsFactory};
1010
use actix_rt::System;
1111
use actix_web::{dev::Server as ActixServer, web::ServiceConfig, App, HttpServer};
1212
use futures::sync::oneshot::{self, Receiver};
@@ -120,26 +120,26 @@ fn load_priv_key(path: &str) -> ServerResult<PrivateKey> {
120120
Ok(priv_keys.pop().unwrap())
121121
}
122122

123-
fn create_cors_factory(cors_cfg: CorsConfig) -> impl Fn() -> Cors + Clone + Send + 'static {
123+
fn create_cors_factory(cors_cfg: CorsConfig) -> impl Fn() -> CorsFactory + Clone + Send + 'static {
124124
let cors_cfg_shared = Arc::new(cors_cfg);
125125
move || create_cors(&*cors_cfg_shared)
126126
}
127127

128-
fn create_cors(cors_cfg: &CorsConfig) -> Cors {
128+
fn create_cors(cors_cfg: &CorsConfig) -> CorsFactory {
129129
let mut cors = Cors::new();
130130
if let Some(max_age_secs) = cors_cfg.max_age_secs {
131131
cors = cors.max_age(max_age_secs as usize);
132132
}
133133
for origin in &cors_cfg.allowed_origins {
134134
cors = cors.allowed_origin(origin);
135135
}
136-
cors
136+
cors.finish()
137137
}
138138

139139
fn start_server_curr_sys(
140140
address: impl ToSocketAddrs,
141141
tls_config_opt: Option<ServerConfig>,
142-
cors_factory: Option<impl Fn() -> Cors + Clone + Send + 'static>,
142+
cors_factory: Option<impl Fn() -> CorsFactory + Clone + Send + 'static>,
143143
app_config: impl FnOnce(&mut ServiceConfig) + Clone + Send + 'static,
144144
) -> ServerResult<ActixServer> {
145145
// This macro-based pseud generic is needed because addition of CORS changes server type.
@@ -163,8 +163,8 @@ fn start_server_curr_sys(
163163
None => server.bind(address),
164164
}
165165
.map_err(Error::BindFailed)?;
166-
let server_addr = server.start();
167-
Ok(server_addr)
166+
let actix_server = server.run();
167+
Ok(actix_server)
168168
}}
169169
}
170170

0 commit comments

Comments
 (0)