Skip to content

Commit

Permalink
Rename app and add middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
tyleragreen committed Jul 10, 2024
1 parent 59d3e35 commit 81abaf8
Show file tree
Hide file tree
Showing 29 changed files with 47 additions and 14 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[workspace]
members = ["tulsa", "app"]
resolver = "2"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

Learning Rust by building a scheduler for both async and sync tasks. This repo is separated into the following areas:
1. `tulsa`: scheduling library which has both thread and coroutine support
1. `example-app`: a sample REST API built on Axum which uses tulsa to run tasks
1. `app`: a sample REST API built on Axum which uses tulsa to run tasks
1. `load-test`: WIP experiments to compare the resource utilization of threads vs coroutines
4 changes: 3 additions & 1 deletion example-app/Cargo.toml → app/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "gtfs_realtime_rust"
name = "app"
version = "0.1.0"
edition = "2021"

Expand All @@ -26,6 +26,8 @@ mime = { version = "0.3.17", optional = true }
mockito = { version = "1.1.0", optional = true }
hyper-util = { version = "0.1.1", features = ["full"] }
http-body-util = "0.1.0"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"

[build-dependencies]
prost-build = { version = "0.12", optional = true }
Expand Down
16 changes: 8 additions & 8 deletions example-app/README.md → app/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# gtfs-realtime-rust
# app

This is a Rust learning exercise to build a REST server that dynamically launches and manages a set of async tasks. These tasks fetch a GTFS-Realtime feed from an endpoint supplied during a POST call. The tasks are scheduled using the `tulsa` scheduler from this repo.

## Example
Some tokio details are not shown here, but these are the initialization steps.
```
use gtfs_realtime_rust::api;
use gtfs_realtime_rust::scheduler::{build, Mode};
Some `tokio` details are not shown here, but these are the initialization steps.
```rust
use app::api;
use app::scheduler::{build, Mode};

# using coroutine scheduling
let interface = build(Mode::Async);
Expand All @@ -18,17 +18,17 @@ axum::serve(listener, router).await.unwrap();
```

## Running Locally
```
```bash
cargo test
cargo run
```
These commands include a few (and hopefully growing number of) re-implemented library crates. I challenged myself to maintain the same interface and learn how these libraries work. To run with the original dependencies, this works.
```
```bash
cargo test --features "use_dependencies"
```

## Sample Feed
```
```json
{
"name": "MTA A Division",
"frequency": 30,
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions example-app/src/api.rs → app/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use axum::{
extract::{Path, State},
http::StatusCode,
middleware::from_fn,
response::IntoResponse,
routing::{get, post},
Json, Router,
};
use std::collections::HashMap;
use std::sync::{Arc, RwLock};

use crate::middleware::log_request;
use crate::models::{CreateFeed, Feed, Status};
use crate::scheduler_interface::ToScheduler;

Expand All @@ -24,13 +26,15 @@ pub fn app(scheduler_interface: Arc<dyn ToScheduler + Send + Sync>) -> Router {
db: Arc::new(RwLock::new(HashMap::new())),
scheduler_interface,
};

Router::new()
.route("/", get(status_handler))
.route(
"/feed/:key",
get(get_handler).put(put_handler).delete(delete_handler),
)
.route("/feed", post(post_handler).get(list_handler))
.layer(from_fn(log_request))
.with_state(state)
}

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions example-app/src/lib.rs → app/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod api;
pub mod fetcher;
pub mod middleware;
pub mod models;
pub mod scheduler_interface;

Expand Down
8 changes: 6 additions & 2 deletions example-app/src/main.rs → app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ use std::net::SocketAddr;
use tokio::net::TcpListener;
use tokio::runtime::Builder;

use gtfs_realtime_rust::api;
use gtfs_realtime_rust::scheduler_interface::{build, Mode};
use app::api;
use app::scheduler_interface::{build, Mode};

fn main() {
// Initialize tracing subscriber for logging
tracing_subscriber::fmt::init();

let address = SocketAddr::from(([0, 0, 0, 0], 3000));
println!("Starting server on {}.", address);

let interface = build(Mode::Async);

// We use a runtime::Builder to specify the number of threads and
// their name.
//
// If we didn't want these customizations, we could just use #[tokio:main]
// to launch a runtime automatically.
let runtime = Builder::new_multi_thread()
Expand Down
19 changes: 19 additions & 0 deletions app/src/middleware.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use axum::{
body::Body,
http::{Request, Response},
middleware::Next,
};
use std::convert::Infallible;
use tracing::info;

// Middleware function to log requests
pub async fn log_request(req: Request<Body>, next: Next) -> Result<Response<Body>, Infallible> {
let method = req.method().clone();
let uri = req.uri().clone();
info!("Incoming request: {} {}", method, uri);

// Call the next middleware or handler
let response = next.run(req).await;

Ok(response)
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ mod tests {
use tokio::net::TcpListener;
use tokio::runtime::Builder;

use gtfs_realtime_rust::api;
use gtfs_realtime_rust::scheduler_interface::{build, Mode};
use app::api;
use app::scheduler_interface::{build, Mode};

fn run(mode: Mode) {
let interface = build(mode);
Expand Down

0 comments on commit 81abaf8

Please sign in to comment.