• Stars
    star
    171
  • Rank 222,266 (Top 5 %)
  • Language
    Rust
  • License
    MIT License
  • Created almost 3 years ago
  • Updated 5 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.
30,622
star
2

matchit

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

papaya

A fast and ergonomic concurrent hash-table for read-heavy workloads.
Rust
341
star
4

seize

Fast, efficient, and robust memory reclamation for Rust.
Rust
340
star
5

boxcar

A concurrent, append-only vector.
Rust
122
star
6

too-many-web-servers

https://ibraheem.ca/posts/too-many-web-servers/
Rust
98
star
7

awaitgroup

Wait for a collection of async tasks to finish.
Rust
32
star
8

dotfiles

My dotfiles for zsh, vim, i3, polybar, alacritty ...
Lua
23
star
9

httprouter-rs

A fast, minimal HTTP framework.
Rust
17
star
10

ripc

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

firefly

High performance concurrent channels.
Rust
7
star
12

derive-alias

Alias mutliple derives as one.
Rust
7
star
13

mongo_beautiful_logger

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

jiffy

Rust implementation of the Jiffy MPSC queue.
Rust
4
star
15

platoon

A lightweight async runtime, for education purposes.
Rust
4
star
16

agilely

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

bison

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

ibraheemdev

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

turbofish

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

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
21

concurrent-dictionary

A port of C#'s ConcurrentDictionary to Rust.
Rust
1
star
22

papaya-db

Rust
1
star
23

dangerous-shell-commands

1
star