<commit_before># Alacrity

A tcp load balancer written in Rust.

## Design

Alacrity uses coroutines to take advantage of async-IO and threads to maximize throughput.

HAProxy is really big on making the stats easy. It does this using a webpage though. I wonder if I should consider adding a simple API for things like stats and high level monitoring.

### Clustering

For clustiner, Alacrity must be setup using DNS round-robin.

### High Availability

Alacrity has an active/passive setup that works out of the box.

## HA Proxy

Example HA Proxy config: http://www.haproxy.org/download/1.4/doc/configuration.txt

## License

Licensing this under GPL (not sure version) or a commercial license. Is this compatible with MPL, MIT and Apache licenses?


## Running

   * `cargo run --bin test-server`
   * `cargo run --bin alacrity`
   * `echo "hi" | nc localhost 8080`

### Tokio notes

[13:40:24]  <moosnat>	Service is explained pretty well in the medium post -- basically a composable middleware
[13:40:31]  <moosnat>	I don't really understand the others though
[14:16:35]  <tikue>	moosnat: transport basically encodes how to read and write messages 
[14:16:56]  <tikue>	moosnat: readiness is how the transport tells the event loop that read or write should be invoked on any given tick
[14:17:33]  <tikue>	so service = application layer, transport = the application's underlying protocol, whether that is http or some other custom protocol
[14:17:55]  <moosnat>	tikue: so I'd write the communication logic in the transport
[14:18:02]  <tikue>	moosnat: the nice thing is that, if you're using a common transport like http, you don't have to write it yourself, and you just have to concern yourself with the Service layer
[14:18:04]  <moosnat>	the high-level application in service

[16:43:14]  <~carllerche>	tikue: moosnat: you can stack transports. Pipeline is actually not a transport
[16:43:32]  <~carllerche>	Pipeline is the task implementation. It takes a transport and exposes it as a service.
[16:43:59]  <~carllerche>	Pipeline is a reusable glue layer between transport and service
[16:44:07]  <~carllerche>	For pipeline based protocols<commit_msg>Update README with some high level design thoughts<commit_after># Alacrity

A tcp proxy written in Rust.

## Design

The goal is to build a proxy that works well in the dynamic VM/container environments that are starting to be more common.

   * Servers must register with the proxy using an HTTP POST to the management IP.
      * The POST payload contains the health check information.
   * The proxy will keep that server active in the pool as long as the health succeeds.
   * The pool is managed by Raft, allowing a cluster of redundant proxy servers. This should allow an active/passive setup out of the box.
      * Note: The [raft-rs](https://github.com/Hoverbear/raft-rs) crate does not currently support dynamic membership.
   * Async IO is done using tokio-core (which is built on top of mio).

Credit to Hoverbear who talked through some of the design with me.

## Running Protype

   * `cargo run --bin test-server`
   * `cargo run --bin alacrity`
   * `echo "hi" | nc localhost 8080`

## High Level Roadmap

   * [x] Proxy prototype using tokio-core
   * [ ] Create Server pool
   * [ ] Management API
   * [ ] Support health checks
   * [ ] Server pool managed by raft

## Management API Design

### Adding A Server

```
POST /servers

{
   "ip": "192.168.3.11",
   "port": "8080",
   "check": {
      "type": "tcp"
   }
}
```

### Removing A Server

Note: It is more common for a server to fall out of the pool after `n` health checks fail.

```
DELETE /servers/:id
```

### Stats

```
GET /stats
```

```
{
   "client": {
      "success": 34534,
      "failed": 33,
   },
   "server": {
      "success": 33770,
      "failed": 15,
   }
}
```

#### Detailed Stats

```
GET /stats/detail
```

```
[{
   "id": "...",
   "ip": "127.0.0.1",
   "port": "8080",
   "success": 33770,
   "failed": 15,
},{
   ...
}]
```

## License

Dunno yet!
{'fraction_non_alphanumeric': 0.1015215764529808, 'fraction_numerical': 0.03142928411075081, 'mean_word_length': 3.577625570776256, 'pattern_counts': {'":': 15, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1230617', 'n_tokens_mistral': 1355, 'n_tokens_neox': 1227, 'n_words': 542}