Request routing forwards each incoming request to the component responsible for processing it. In partitioned systems, effective routing sends requests to the server with the fastest access to the required data; poor steering preserves partitioning but adds latency. section 5.4 section 5.0
Use routing as part of the partitioning design, while accounting for its operational trade-offs:
- Route requests to the partition hosting the needed data to minimize communication and access latency. section 5.4
- Balance accesses across partitions because uneven demand can undermine the benefits of independent data subsets. section 5.0
- Choose among direct, proxy, and forward routing strategies; the routing decision adds application complexity even as partitioning reduces coordination. section 5.7 section 5.0
Node IDs and round-robin requests
A partitioned REST API can assign each server a numeric node ID and listen on port 8080 plus that ID. A partition-aware HTTP benchmark accepts the node count, builds the node URLs, and sends requests round-robin. Comparing one node with five shows lower tail latency for five nodes because requests can execute in parallel. This demonstrates routing infrastructure, but not yet a data-based partitioning strategy. section 5.6
Listing 5.1 REST API server with embedded SQLite and node ID configuration
use actix_web::{
error::ErrorInternalServerError, web, App, Error,
HttpServer,
};
use clap::Parser;
use rusqlite::Connection;
use std::env;
use std::sync::{Arc, Mutex};
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// ID of the node.
#[arg(short, long)]
id: u16,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let args = Args::parse();
let port = 8080 + args.id;
let listen_addr = format!("127.0.0.1:{}", port);
let database_url = env::var("DATABASE_URL")?;
let conn = Arc::new(Mutex::new(Connection::open(
database_url,
)?));
let app = move || {
App::new()
.app_data(web::Data::new(conn.clone()))
.service(
web::resource("/hello")
.route(web::get().to(say_hello)),
)
};
Ok(HttpServer::new(app)
.bind(listen_addr)?
.run()
.await?)
}
async fn say_hello(
conn: web::Data<Arc<Mutex<Connection>>>,
) -> anyhow::Result<String, Error> {
let conn = conn.lock().unwrap();
let result = conn
.query_row("SELECT 'hello world'", [], |row| {
row.get(0)
})
.map_err(ErrorInternalServerError)?;
Ok(result)
}
Inspect the Rust REST API implementation that converts a node ID into a listening port and exposes the routed service. section 5.6





















