• Stars
    star
    161
  • Rank 226,308 (Top 5 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 2 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Rust web servers without async/await.

Astra

Crate Github Docs

A blocking HTTP server built on top of hyper.

use astra::{Body, Response, Server};

fn main() {
    Server::bind("localhost:3000")
        .serve(|_req, _info| Response::new(Body::new("Hello World!")))
        .expect("serve failed");
}

How Does It Work?

Hyper is built on async I/O and depends on it to run correctly. To avoid depending on a large crate like Tokio, Astra runs a small evented I/O loop on a background thread and dispatches connections to it's own worker pool. The difference is that instead of tasks yielding to a userspace runtime like Tokio, they yield to the operating system. This means that request handlers can use standard I/O primitives without worrying about blocking the runtime:

use astra::{Body, ResponseBuilder, Server};
use std::time::Duration;

fn main() {
    Server::bind("localhost:3000")
        .serve(|_req, _info| {
            // Putting the worker thread to sleep will allow
            // other workers to run.
            std::thread::sleep(Duration::from_secs(1));

            // Regular blocking I/O is fine too!
            let body = std::fs::read_to_string("index.html").unwrap();

            ResponseBuilder::new()
                .header("Content-Type", "text/html")
                .body(Body::new(body))
                .unwrap()
        })
        .expect("serve failed");
}

Features

Astra supports both HTTP/1 and HTTP/2 with most the configuration options that Hyper exposes. Features that depend on Tokio however, such as http2_keep_alive_while_idle, are not supported and blocked on better hyper support.

Astra is currently an HTTP server library only. The client API is unimplemented.

Security

One of the issues with blocking I/O is that it is susceptible to attacks such as Slowloris. Because of this, it is important to run your server behind an async reverse proxy such as Nginx. You were likely going to doing this anyways for TLS support, but it is something to keep in mind.

But Is It Fast?

Many of the references you'll find about thread-per-request performance are very outdated, often referencing bottlenecks from a time where C10k was peak scale. Since then, thread creation has gotten significantly cheaper, and context switching overhead has been reduced drastically. Modern OS schedulers are much better than they are given credit for, and it is now very feasible to serve upwards of tens of thousands of concurrent connections using blocking I/O.

In naive "Hello World" style HTTP benchmarks, Astra is likely to lag behind Tokio. This is partly because Astra has to pay the cost of both threading and async I/O to be compatible with Hyper. However, as more work is done per request, especially pure blocking I/O, the difference diminishes. As always, you should measure your own use case, but Astra's performance may surprise you.

That being said, one of Astra's main use cases is running a lightweight server with minimal dependencies, and avoiding the complexity that comes with async, so any potential performance tradeoffs might not be be relevant.

More Repositories

1

modern-unix

A collection of modern/faster/saner alternatives to common unix commands.
29,534
star
2

matchit

A high performance, zero-copy URL router.
Rust
311
star
3

seize

Fast, efficient, and robust memory reclamation for Rust.
Rust
299
star
4

boxcar

A concurrent, append-only vector.
Rust
100
star
5

too-many-web-servers

https://ibraheem.ca/posts/too-many-web-servers/
Rust
80
star
6

awaitgroup

Wait for a collection of async tasks to finish.
Rust
28
star
7

dotfiles

My dotfiles for zsh, vim, i3, polybar, alacritty ...
Lua
24
star
8

httprouter-rs

A fast, minimal HTTP framework.
Rust
16
star
9

ripc

A C compiler, written in Rust.
Rust
9
star
10

firefly

High performance concurrent channels.
Rust
6
star
11

derive-alias

Alias mutliple derives as one.
Rust
6
star
12

jiffy

Rust
4
star
13

platoon

A lightweight async runtime for Rust.
Rust
4
star
14

mongo_beautiful_logger

A simple and beautiful logger gem for MongoDB in you Ruby/Rails app.
Ruby
4
star
15

agilely

Agilely is an open source project management solution for individuals and teams alike.
Ruby
4
star
16

bison

A powerful web-application framework that does the heavy lifting for you.
Rust
2
star
17

ibraheemdev

Ibraheem Ahmed | Software developer. Open source enthusiast. Freelancer.
SCSS
1
star
18

turbofish

A fast, executor agnostic HTTP implementation in Rust.
Rust
1
star
19

go-chatrooms-example

This application shows how to use the websocket package to implement a simple web chat application with multiple rooms
Go
1
star
20

seize-hashmap

A Rust concurrent HashMap optimized for read-heavy workloads.
Rust
1
star
21

tictactoe

A react powered tictactoe app
JavaScript
1
star
22

papaya-db

Rust
1
star
23

dangerous-shell-commands

1
star