From 4e695e0d139e4aab0b447dc2d0f00f16f7e92c95 Mon Sep 17 00:00:00 2001 From: chinyuchan Date: Sat, 24 Feb 2024 17:32:24 +0800 Subject: [PATCH] cache price. --- explorer/src/service/api.rs | 8 +- explorer/src/service/v1/price.rs | 74 +++++++++++++------ .../20220218070358_create_tables.up.sql | 6 ++ 3 files changed, 64 insertions(+), 24 deletions(-) diff --git a/explorer/src/service/api.rs b/explorer/src/service/api.rs index 51fbe46..c98dc55 100644 --- a/explorer/src/service/api.rs +++ b/explorer/src/service/api.rs @@ -484,7 +484,9 @@ impl Api { ids: Query, vs_currencies: Query, ) -> poem::Result { - service::v1::price::simple_price(ids, vs_currencies).await + service::v1::price::simple_price(self, ids, vs_currencies) + .await + .map_err(handle_fetch_one_err) } #[oai( @@ -499,7 +501,9 @@ impl Api { interval: Query>, days: Query, ) -> poem::Result { - service::v1::price::market_chart(id, vs_currency, interval, days).await + service::v1::price::market_chart(id, vs_currency, interval, days) + .await + .map_err(handle_fetch_one_err) } #[oai(path = "/address/count", method = "get", tag = "ApiTags::Address")] diff --git a/explorer/src/service/v1/price.rs b/explorer/src/service/v1/price.rs index ef3a8e1..14be7fd 100644 --- a/explorer/src/service/v1/price.rs +++ b/explorer/src/service/v1/price.rs @@ -1,8 +1,12 @@ +use crate::service::api::Api; +use anyhow::Result; +use log::error; use poem_openapi::param::{Path, Query}; use poem_openapi::types::Type; use poem_openapi::{payload::Json, ApiResponse, Object}; use serde::{Deserialize, Serialize}; use serde_json::Value; +use sqlx::Row; #[derive(ApiResponse)] pub enum SimplePriceResponse { @@ -20,7 +24,7 @@ pub enum SimplePriceResponse { pub struct SimplePriceResult { pub code: i32, pub message: String, - pub data: SimplePrice, + pub data: Option, } #[derive(Serialize, Deserialize, Debug, Default, Object)] @@ -49,14 +53,36 @@ pub enum MarketChartResponse { pub struct MarketChartResult { pub code: i32, pub message: String, - pub data: FraMarketChart, + pub data: Option, +} + +pub async fn get_fra_price(api: &Api) -> Result { + let mut conn = api.storage.lock().await.acquire().await?; + let row = sqlx::query("SELECT price FROM prices") + .fetch_one(&mut conn) + .await?; + let p: String = row.try_get("price")?; + let fra_price = FraPrice { usd: p.parse()? }; + Ok(fra_price) +} + +pub async fn upsert_fra_price(api: &Api, price: &str) -> Result<()> { + let mut conn = api.storage.lock().await.acquire().await?; + sqlx::query("INSERT INTO prices VALUES($1,$2) ON CONFLICT(name) DO UPDATE SET price=$2") + .bind("fra") + .bind(price) + .execute(&mut conn) + .await?; + + Ok(()) } #[allow(clippy::let_unit_value)] pub async fn simple_price( + api: &Api, ids: Query, vs_currencies: Query, -) -> poem::Result { +) -> Result { if ids.is_empty() || vs_currencies.is_empty() { return Ok(SimplePriceResponse::BadRequest); } @@ -67,29 +93,33 @@ pub async fn simple_price( ); let resp1 = reqwest::get(url).await; if let Err(e) = resp1 { - return Ok(SimplePriceResponse::InternalError(Json( - SimplePriceResult { - code: 500, - message: e.to_string(), - data: Default::default(), - }, - ))); + error!("Get FRA price: {}", e.to_string()); + let fra_price = get_fra_price(api).await?; + return Ok(SimplePriceResponse::Ok(Json(SimplePriceResult { + code: 200, + message: "".to_string(), + data: Some(SimplePrice { findora: fra_price }), + }))); } + let resp2 = resp1.unwrap().json::().await; if let Err(e) = resp2 { - return Ok(SimplePriceResponse::InternalError(Json( - SimplePriceResult { - code: 500, - message: e.to_string(), - data: Default::default(), - }, - ))); + error!("Parse FRA price: {}", e.to_string()); + let fra_price = get_fra_price(api).await?; + return Ok(SimplePriceResponse::Ok(Json(SimplePriceResult { + code: 200, + message: "".to_string(), + data: Some(SimplePrice { findora: fra_price }), + }))); } + let fra_price = resp2.unwrap().findora; + upsert_fra_price(api, fra_price.usd.to_string().as_str()).await?; + Ok(SimplePriceResponse::Ok(Json(SimplePriceResult { code: 200, message: "".to_string(), - data: resp2.unwrap(), + data: Some(SimplePrice { findora: fra_price }), }))) } @@ -106,7 +136,7 @@ pub async fn market_chart( vs_currency: Query, interval: Query>, days: Query, -) -> poem::Result { +) -> Result { if id.is_empty() || vs_currency.is_empty() || days.is_empty() { return Ok(MarketChartResponse::BadRequest); } @@ -124,7 +154,7 @@ pub async fn market_chart( MarketChartResult { code: 500, message: e.to_string(), - data: Default::default(), + data: None, }, ))); } @@ -134,7 +164,7 @@ pub async fn market_chart( MarketChartResult { code: 500, message: e.to_string(), - data: Default::default(), + data: None, }, ))); } @@ -145,6 +175,6 @@ pub async fn market_chart( Ok(MarketChartResponse::Ok(Json(MarketChartResult { code: 200, message: "".to_string(), - data: fmc, + data: Some(fmc), }))) } diff --git a/module/migrations/20220218070358_create_tables.up.sql b/module/migrations/20220218070358_create_tables.up.sql index 3b8abbb..aa44d29 100644 --- a/module/migrations/20220218070358_create_tables.up.sql +++ b/module/migrations/20220218070358_create_tables.up.sql @@ -179,3 +179,9 @@ create index n2e_sender_index on n2e(sender); create index n2e_receiver_index on n2e(receiver); create index n2e_time_index on n2e(timestamp); create index n2e_height_index on n2e(height); + +create table prices( + name varchar(8) not null, + price varchar(16) not null, + primary key (name) +);