Skip to content

Commit

Permalink
Move Serve Functionality Into Inherent Impl On ServeArgs
Browse files Browse the repository at this point in the history
  • Loading branch information
harrysolovay committed Sep 25, 2024
1 parent cecdf24 commit d1122e6
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 64 deletions.
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
edition = "2021"
group_imports = "StdExternalCrate"
imports_granularity = "Crate"
max_width = 120
newline_style = "Unix"
Expand Down
66 changes: 2 additions & 64 deletions server/src/bin/mina_ocv.rs
Original file line number Diff line number Diff line change
@@ -1,70 +1,8 @@
use anyhow::Result;
use axum::{
debug_handler,
extract::{Path, State},
response::{IntoResponse, Response},
routing::get,
serve as axum_serve, Json, Router,
};
use clap::Parser;
use mina_ocv::{shutdown_signal, Ocv, OcvConfig, Wrapper};
use std::sync::Arc;
use tokio::net::TcpListener;
use tower_http::cors::CorsLayer;

#[derive(Clone, Parser)]
struct ServeArgs {
/// API Host.
#[clap(long, env, default_value = "0.0.0.0")]
pub host: String,
/// API Port.
#[clap(long, env, default_value = "8080")]
pub port: u16,
/// OCV Args.
#[command(flatten)]
pub config: OcvConfig,
}
use mina_ocv::ServeArgs;

#[tokio::main]
async fn main() -> Result<()> {
let ServeArgs { host, port, config } = ServeArgs::parse();
tracing_subscriber::fmt::init();

let listener = TcpListener::bind(format!("{}:{}", host, port)).await?;
tracing::info!("Starting server at http://{}.", listener.local_addr()?);

let ocv = config.to_ocv().await?;
let router = Router::new()
.route("/api/info", get(get_info))
.route("/api/proposals", get(get_proposals))
.route("/api/proposal/:id", get(get_proposal))
.route("/api/proposal/:id/results", get(get_proposal_result))
.layer(CorsLayer::permissive())
.with_state(Arc::new(ocv));
axum_serve(listener, router).with_graceful_shutdown(shutdown_signal()).await?;
Ok(())
}

#[debug_handler]
async fn get_info(ctx: State<Arc<Ocv>>) -> Response {
tracing::info!("get_info");
Wrapper(ctx.info().await).into_response()
}

#[debug_handler]
async fn get_proposals(ctx: State<Arc<Ocv>>) -> Response {
tracing::info!("get_proposals");
Json(ctx.proposals.clone()).into_response()
}

#[debug_handler]
async fn get_proposal(ctx: State<Arc<Ocv>>, Path(id): Path<usize>) -> Response {
tracing::info!("get_proposal {}", id);
Wrapper(ctx.proposal(id).await).into_response()
}

#[debug_handler]
async fn get_proposal_result(ctx: State<Arc<Ocv>>, Path(id): Path<usize>) -> Response {
tracing::info!("get_proposal_result {}", id);
Wrapper(ctx.proposal_result(id).await).into_response()
ServeArgs::parse().serve().await
}
2 changes: 2 additions & 0 deletions server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod config;
mod ledger;
mod ocv;
mod proposals;
mod serve;
mod util;
mod vote;

Expand All @@ -11,5 +12,6 @@ pub use config::*;
pub use ledger::*;
pub use ocv::*;
pub use proposals::*;
pub use serve::*;
pub use util::*;
pub use vote::*;
72 changes: 72 additions & 0 deletions server/src/serve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use std::sync::Arc;

use anyhow::Result;
use axum::{
Json, Router, debug_handler,
extract::{Path, State},
response::IntoResponse,
routing::get,
serve as axum_serve,
};
use clap::Parser;
use tokio::net::TcpListener;
use tower_http::cors::CorsLayer;

use crate::{Ocv, OcvConfig, Wrapper, shutdown_signal};

#[derive(Clone, Parser)]
pub struct ServeArgs {
/// API Host.
#[clap(long, env, default_value = "0.0.0.0")]
pub host: String,
/// API Port.
#[clap(long, env, default_value = "8080")]
pub port: u16,
/// OCV Args.
#[command(flatten)]
pub config: OcvConfig,
}

impl ServeArgs {
pub async fn serve(&self) -> Result<()> {
tracing_subscriber::fmt::init();

let listener = TcpListener::bind(format!("{}:{}", self.host, self.port)).await?;
tracing::info!("Starting server at http://{}.", listener.local_addr()?);

let ocv = self.config.to_ocv().await?;
let router = Router::new()
.route("/api/info", get(get_info))
.route("/api/proposals", get(get_proposals))
.route("/api/proposal/:id", get(get_proposal))
.route("/api/proposal/:id/results", get(get_proposal_result))
.layer(CorsLayer::permissive())
.with_state(Arc::new(ocv));
axum_serve(listener, router).with_graceful_shutdown(shutdown_signal()).await?;
Ok(())
}
}

#[debug_handler]
async fn get_info(ctx: State<Arc<Ocv>>) -> impl IntoResponse {
tracing::info!("get_info");
Wrapper(ctx.info().await)
}

#[debug_handler]
async fn get_proposals(ctx: State<Arc<Ocv>>) -> impl IntoResponse {
tracing::info!("get_proposals");
Json(ctx.proposals.to_owned())
}

#[debug_handler]
async fn get_proposal(ctx: State<Arc<Ocv>>, Path(id): Path<usize>) -> impl IntoResponse {
tracing::info!("get_proposal {}", id);
Wrapper(ctx.proposal(id).await)
}

#[debug_handler]
async fn get_proposal_result(ctx: State<Arc<Ocv>>, Path(id): Path<usize>) -> impl IntoResponse {
tracing::info!("get_proposal_result {}", id);
Wrapper(ctx.proposal_result(id).await)
}

0 comments on commit d1122e6

Please sign in to comment.