Skip to content

Commit

Permalink
Merge pull request #2 from traP-jp/i-couldnt-sleep
Browse files Browse the repository at this point in the history
I couldn't sleep
  • Loading branch information
H1rono authored Jan 19, 2025
2 parents 7e6c591 + d46d7c6 commit ee19fd1
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 4 deletions.
Empty file added proto/.gitkeep
Empty file.
6 changes: 6 additions & 0 deletions server/.env.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
MYSQL_HOSTNAME=localhost
MYSQL_PORT=3306
MYSQL_USER=h24w14
MYSQL_PASSWORD=password
MYSQL_DATABASE=h24w14
RUST_LOG=debug
2 changes: 2 additions & 0 deletions server/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ target/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

.env
45 changes: 45 additions & 0 deletions server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ anyhow = { version = "1.0.95", features = ["backtrace"] }
async-stream = "0.3.6"
async-trait = "0.1.85"
axum.version = "0.8.1"
axum.features = ["http2"]
axum.features = ["http2", "ws"]
bytes = "1.9.0"
chrono = { version = "0.4.39", features = ["serde"] }
futures = "0.3.31"
Expand Down
2 changes: 1 addition & 1 deletion server/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
// TODO
pub mod router;
101 changes: 99 additions & 2 deletions server/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,100 @@
fn main() {
println!("Hello, world!");
use anyhow::Context;
use sqlx::MySqlPool;
use tokio::net::TcpListener;

use h24w14 as lib;

#[derive(Debug, Clone)]
struct State {
pool: MySqlPool,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
use futures::TryFutureExt;
use tracing_subscriber::EnvFilter;

let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into());
tracing_subscriber::fmt().with_env_filter(env_filter).init();

let pool = load_mysql_from_env("MYSQL_")
.or_else(|_| load_mysql_from_env("MARIADB_"))
.or_else(|_| load_mysql_from_env("NS_MARIADB_"))
.await?;
let state = std::sync::Arc::new(State { pool });

let router = lib::router::make(state);
let tcp_listener = load_tcp_listener().await?;
axum::serve(tcp_listener, router)
.with_graceful_shutdown(shutdown())
.await?;

Ok(())
}

// MARK: helper `fn`s

#[tracing::instrument]
async fn load_mysql_from_env(prefix: &str) -> anyhow::Result<MySqlPool> {
macro_rules! var {
($n:ident) => {{
let var_name = format!(concat!("{}", stringify!($n)), prefix);
std::env::var(&var_name).with_context(|| format!("Failed to read {var_name}"))
}};
}

let hostname = var!(HOSTNAME)?;
let user = var!(USER)?;
let password = var!(PASSWORD)?;
let port: u16 = var!(PORT)?.parse().context("Failed to read PORT value")?;
let database = var!(DATABASE)?;
let options = sqlx::mysql::MySqlConnectOptions::new()
.host(&hostname)
.username(&user)
.password(&password)
.port(port)
.database(&database);
sqlx::MySqlPool::connect_with(options)
.await
.inspect_err(|e| {
tracing::error!(
error = e as &dyn std::error::Error,
"Failed to connect database"
)
})
.context("Failed to connect to MySQL")
}

#[tracing::instrument]
async fn load_tcp_listener() -> anyhow::Result<TcpListener> {
let port: u16 = std::env::var("PORT")
.unwrap_or_else(|_| 8000.to_string())
.parse()
.context("Failed to parse PORT value")?;
let addr: std::net::SocketAddr = ([0, 0, 0, 0], port).into();
let listener = TcpListener::bind(addr)
.await
.with_context(|| format!("Failed to bind {addr}"))?;
tracing::info!(%addr, "Listening");
Ok(listener)
}

#[tracing::instrument]
async fn shutdown() {
let ctrl_c = tokio::signal::ctrl_c();
match ctrl_c.await {
Ok(()) => tracing::info!("Received ctrl-c"),
Err(e) => tracing::error!(
error = &e as &dyn std::error::Error,
"Failed to watch ctrl-c"
),
}
}

// MARK: State `impl`s

impl AsRef<MySqlPool> for State {
fn as_ref(&self) -> &MySqlPool {
&self.pool
}
}
26 changes: 26 additions & 0 deletions server/src/router.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::sync::Arc;

use axum::Router;
use tower::ServiceBuilder;
use tower_http::trace::TraceLayer;

pub fn make<State: Send + Sync + 'static>(state: Arc<State>) -> Router<()> {
let grpcs = grpc_routes(state.clone());
let others = other_routes(state.clone());
Router::merge(grpcs, others)
}

fn grpc_routes<State: Send + Sync + 'static>(_state: Arc<State>) -> Router<()> {
// TODO
Router::new()
}

fn other_routes<State: Send + Sync + 'static>(state: Arc<State>) -> Router<()> {
use axum::routing;

let layer = ServiceBuilder::new().layer(TraceLayer::new_for_http());
Router::new()
.route("/ping", routing::get(|| async { "pong".to_string() }))
.with_state(state)
.layer(layer)
}

0 comments on commit ee19fd1

Please sign in to comment.