Skip to content

Commit

Permalink
runtime: add edge name in x-served-by header
Browse files Browse the repository at this point in the history
  • Loading branch information
fuxiaohei committed Aug 27, 2023
1 parent d1cf341 commit 2ceb08c
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 14 deletions.
9 changes: 7 additions & 2 deletions binary/edge/src/localip.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use anyhow::Result;
use land_core::confdata::RegionIPInfo;
use std::sync::OnceLock;
use once_cell::sync::OnceCell;
use tracing::{debug, info, instrument};

const IPINFO_LINK: &str = "https://ipinfo.io/json";
const IPINFO_LOCAL_FILE: &str = "ipinfo.json";
pub static IPINFO: OnceLock<RegionIPInfo> = OnceLock::new();

// IPINFO is the local ip info
pub static IPINFO: OnceCell<RegionIPInfo> = OnceCell::new();
// REGION_NAME is the region name
pub static REGION_NAME: OnceCell<String> = OnceCell::new();

/*
{
Expand Down Expand Up @@ -35,6 +39,7 @@ pub async fn init() -> Result<()> {
}
};
info!("ip : {:?}, region: {}", ip, ip.region());
REGION_NAME.get_or_init(|| ip.region());
IPINFO.get_or_init(|| ip);
Ok(())
}
Expand Down
8 changes: 6 additions & 2 deletions binary/edge/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ async fn sync_handler(Json(mut payload): Json<RuntimeData>) -> Response<Body> {
let mut runtimes = RUNTIMES.lock().unwrap();
runtimes.insert(payload.hostname.clone(), payload);

let builder = Response::builder().status(204);
builder.body(Body::empty()).unwrap()
let builder = Response::builder().status(200);
let body = serde_json::to_string(&land_core::confdata::RuntimeRecvData {
region_name: crate::localip::REGION_NAME.get().unwrap().clone(),
})
.unwrap();
builder.body(Body::from(body)).unwrap()
}

pub async fn start(addr: SocketAddr) -> Result<()> {
Expand Down
28 changes: 23 additions & 5 deletions binary/runtime/src/edge.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use envconfig::Envconfig;
use land_core::confdata::RuntimeData;
use once_cell::sync::OnceCell;
use sysinfo::{CpuExt, System, SystemExt};
use tracing::{debug, info, instrument, warn};

Expand All @@ -9,16 +10,20 @@ pub struct Config {
addr: String,
#[envconfig(from = "EDGE_SYNC_ENABLED", default = "true")]
sync_enabled: bool,
#[envconfig(from = "EDGE_SYNC_INTERVAL", default = "1")]
#[envconfig(from = "EDGE_SYNC_INTERVAL", default = "5")]
sync_interval: u64,
}

/// SERVER_NAME is the name of region
pub static SERVER_NAME: OnceCell<String> = OnceCell::new();

#[instrument(skip_all, name = "[EDGE]")]
async fn sync_interval(cfg: Config) {
let mut interval = tokio::time::interval(std::time::Duration::from_secs(cfg.sync_interval));

let mut sys = System::new_all();
let url = format!("{}/v1/sync", cfg.addr);
let client = reqwest::Client::new();

loop {
interval.tick().await;
Expand All @@ -40,19 +45,32 @@ async fn sync_interval(cfg: Config) {
used_memory,
updated_at: now_ts,
};
let client = reqwest::Client::new();

let resp = match client.post(&url).json(&data).send().await {
Ok(resp) => resp,
Err(e) => {
warn!("sync request failed: {}", e);
continue;
}
};
if resp.status().is_success() {
debug!("sync success");
} else {
if !resp.status().is_success() {
warn!("sync responst status failed: {}", resp.status());
// sleep 5s to retry
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
continue;
}

let recv = match resp.json::<land_core::confdata::RuntimeRecvData>().await {
Ok(recv) => recv,
Err(e) => {
warn!("sync response json failed: {}", e);
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
continue;
}
};

debug!("sync recv: {:?}", recv);
SERVER_NAME.get_or_init(|| recv.region_name);
}
}

Expand Down
18 changes: 18 additions & 0 deletions binary/runtime/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ pub async fn wasm_caller_handler(
if builder.headers_ref().unwrap().get("x-request-id").is_none() {
builder = builder.header("x-request-id", req_id.clone());
}
builder = builder.header(
"x-served-by",
crate::edge::SERVER_NAME
.get()
.unwrap_or(&String::from("land-edge")),
);
if wasm_resp.status >= 400 {
warn!( status=%wasm_resp.status, "[Response]");
} else {
Expand Down Expand Up @@ -92,6 +98,12 @@ async fn default_handler(req: Request<Body>) -> Response<Body> {
let _enter = span.enter();
let mut builder = Response::builder().status(404);
builder = builder.header("x-request-id", req_id);
builder = builder.header(
"x-served-by",
crate::edge::SERVER_NAME
.get()
.unwrap_or(&String::from("land-edge")),
);
warn!(status = 404, "[Response] x-land-module not found");
return builder.body(Body::from("x-land-module not found")).unwrap();
}
Expand All @@ -105,6 +117,12 @@ async fn default_handler(req: Request<Body>) -> Response<Body> {
warn!(status = 500, "[Response] {}", e.to_string());
let mut builder = Response::builder().status(500);
builder = builder.header("x-request-id", req_id);
builder = builder.header(
"x-served-by",
crate::edge::SERVER_NAME
.get()
.unwrap_or(&String::from("land-edge")),
);
builder.body(Body::from(e.to_string())).unwrap()
}
}
Expand Down
5 changes: 5 additions & 0 deletions crates/core/src/confdata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ pub struct RegionRecvData {
pub storage_basepath: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RuntimeRecvData {
pub region_name: String,
}

#[derive(Debug)]
/// DomainSetting is the domain settings
pub struct DomainSetting {
Expand Down
10 changes: 5 additions & 5 deletions crates/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Add this to your `Cargo.toml`:
[dependencies]
anyhow = "1.0.75"
http = "0.2.9"
land-sdk = "0.1.0-rc.2"
land-sdk = "0.1.0-rc.3"
wit-bindgen = "0.10.0"

[lib]
Expand All @@ -20,19 +20,19 @@ crate-type = ["cdylib"] # target wasm32-wasi
## Example

```rust
use land_sdk::http::{Body, Request, Response};
use land_sdk::http::{Body, Error, Request, Response};
use land_sdk::http_main;

#[http_main]
pub fn handle_request(req: Request) -> Response {
pub fn handle_request(req: Request) -> Result<Response, Error> {
let url = req.uri().clone();
let method = req.method().to_string().to_uppercase();
http::Response::builder()
Ok(http::Response::builder()
.status(200)
.header("X-Request-Url", url.to_string())
.header("X-Request-Method", method)
.body(Body::from("Hello Runtime.land!!"))
.unwrap()
.unwrap())
}
```

Expand Down

0 comments on commit 2ceb08c

Please sign in to comment.