mirror of
https://github.com/actix/actix-website
synced 2024-11-24 00:41:07 +01:00
Architecture diagrams of HttpServer and Connection lifecycle (#148)
* add arch diagrams and menu * fix colors for arch diagrams * refine architecture diagrams, ready for review * capitalize titles and add mmdc instruction * apply code review requested changes * Add links to accept, worker and dispatcher too
This commit is contained in:
parent
53214f4727
commit
c1a8103cbc
12
README.md
12
README.md
@ -21,6 +21,18 @@ hugo server
|
||||
|
||||
Then visit [http://localhost:1313](http://localhost:1313).
|
||||
|
||||
## Updating diagrams
|
||||
|
||||
Diagrams are located under [/static/css/img/diagrams/](https://github.com/actix/actix-website/tree/master/static/img/diagrams) and built with [Mermaid CLI](https://github.com/mermaidjs/mermaid.cli).
|
||||
|
||||
For instance to edit `connection_overview` diagram:
|
||||
```sh
|
||||
cd static/css/img/diagrams
|
||||
vi connection_overview.mmd
|
||||
# Compile diagrams:
|
||||
mmdc -i connection_overview.mmd -o connection_overview.svg
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
Pretty murky. Right now a massive clone of the tokio website. Will get this
|
||||
|
42
content/docs/conn_lifecycle.md
Normal file
42
content/docs/conn_lifecycle.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Connection Lifecycle
|
||||
menu: docs_architecture
|
||||
weight: 20
|
||||
---
|
||||
|
||||
|
||||
# Architecture overview
|
||||
|
||||
After Server has started listening to all sockets, [`Accept`][Accept] and [`Worker`][Worker] are two main loops responsible for processing incoming client connections.
|
||||
|
||||
Once connection accepted Application level protocol processing happens in a protocol specific [`Dispatcher`][Dispatcher] loop spawned from [`Worker`][Worker].
|
||||
|
||||
Please note, below diagrams are outlining happy-path scenarios only.
|
||||
|
||||
![](/img/diagrams/connection_overview.svg)
|
||||
|
||||
## Accept loop in more detail
|
||||
|
||||
![](/img/diagrams/connection_accept.svg)
|
||||
|
||||
Most of code implementation resides in [`actix-server`][server] crate for struct [`Accept`][Accept].
|
||||
|
||||
## Worker loop in more detail
|
||||
|
||||
![](/img/diagrams/connection_worker.svg)
|
||||
|
||||
Most of code implementation resides in [`actix-server`][server] crate for struct [`Worker`][Worker].
|
||||
|
||||
## Request loop roughly
|
||||
|
||||
![](/img/diagrams/connection_request.svg)
|
||||
|
||||
Most of code implementation for request loop resides in [`actix-web`][web] and [`actix-http`][http] crates.
|
||||
|
||||
|
||||
[server]: https://crates.io/crates/actix-server
|
||||
[web]: https://crates.io/crates/actix-web
|
||||
[http]: https://crates.io/crates/actix-http
|
||||
[Accept]: https://github.com/actix/actix-net/blob/master/actix-server/src/accept.rs
|
||||
[Worker]: https://github.com/actix/actix-net/blob/master/actix-server/src/worker.rs
|
||||
[Dispatcher]: https://github.com/actix/actix-web/blob/master/actix-http/src/h1/dispatcher.rs
|
23
content/docs/http_server_init.md
Normal file
23
content/docs/http_server_init.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: Http Server Initialization
|
||||
menu: docs_architecture
|
||||
weight: 10
|
||||
---
|
||||
|
||||
## Architecture overview
|
||||
|
||||
Below is a diagram of HttpServer initalization, which happens on the following code
|
||||
```rust
|
||||
#[actix_rt::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.route("/", web::to(|| HttpResponse::Ok()))
|
||||
})
|
||||
.bind("127.0.0.1:8088")?
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
```
|
||||
|
||||
![](/img/diagrams/http_server.svg)
|
@ -75,6 +75,17 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h5>Diagrams</h5>
|
||||
<div>
|
||||
<ul class="nav">
|
||||
{{ range .Site.Menus.docs_architecture }}
|
||||
<li{{ if eq $currentURL .URL }} class="active"{{ end }}>
|
||||
<a href="{{ .URL }}">{{ .Name }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h5>API Documentation</h5>
|
||||
<div>
|
||||
<ul class="nav">
|
||||
|
28
static/img/diagrams/connection_accept.mmd
Normal file
28
static/img/diagrams/connection_accept.mmd
Normal file
@ -0,0 +1,28 @@
|
||||
sequenceDiagram
|
||||
|
||||
participant ServerBuilder
|
||||
participant mio
|
||||
participant Accept
|
||||
participant WorkerClient
|
||||
|
||||
|
||||
ServerBuilder->>Accept: start(socks, workers)
|
||||
loop Continuous: poll
|
||||
Accept->>mio: mio::Poll::poll()
|
||||
alt poll() -> TIMER | CMD
|
||||
Accept-->>Accept: process_*
|
||||
else poll() -> NOTIFY
|
||||
Accept->>Accept: backpressure
|
||||
else poll() -> OTHER(token)
|
||||
Accept-->>Accept: accept_one(Conn)
|
||||
loop while exist WorkerClient
|
||||
Accept->>WorkerClient: send(Conn)
|
||||
alt send(Conn) -> Ok(_)
|
||||
Note over Accept: break loop
|
||||
else send(Conn) -> Err(_)
|
||||
Accept->>ServerBuilder: worker_faulted(idx)
|
||||
Accept->>Accept: remove worker, get next worker
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
4
static/img/diagrams/connection_accept.svg
Normal file
4
static/img/diagrams/connection_accept.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 15 KiB |
34
static/img/diagrams/connection_overview.mmd
Normal file
34
static/img/diagrams/connection_overview.mmd
Normal file
@ -0,0 +1,34 @@
|
||||
sequenceDiagram
|
||||
|
||||
participant ServerBuilder
|
||||
participant Accept
|
||||
participant WorkerClient
|
||||
participant Worker
|
||||
participant Dispatcher
|
||||
|
||||
ServerBuilder->>Accept: start(socks, workers)
|
||||
|
||||
Note over Accept: accept Connections
|
||||
loop poll connections on sockets
|
||||
activate Accept
|
||||
Accept-->>Accept: poll() --> Conn
|
||||
Note over Accept: backpressure logic
|
||||
Accept->>WorkerClient: send(Conn)
|
||||
end
|
||||
deactivate Accept
|
||||
|
||||
Note over Worker: process Connections
|
||||
loop Worker as Future::poll
|
||||
activate Worker
|
||||
Worker->>WorkerClient: rx.poll_next()
|
||||
Note over Worker: Service factories
|
||||
Worker-->>Dispatcher: new(stream)
|
||||
end
|
||||
deactivate Worker
|
||||
|
||||
Note over Dispatcher: process Requests
|
||||
loop Dispatcher::poll
|
||||
activate Dispatcher
|
||||
Dispatcher-->>Dispatcher: Dispatch requests
|
||||
end
|
||||
deactivate Dispatcher
|
4
static/img/diagrams/connection_overview.svg
Normal file
4
static/img/diagrams/connection_overview.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 15 KiB |
29
static/img/diagrams/connection_request.mmd
Normal file
29
static/img/diagrams/connection_request.mmd
Normal file
@ -0,0 +1,29 @@
|
||||
sequenceDiagram
|
||||
|
||||
participant HttpServer
|
||||
participant HttpServiceHandler
|
||||
participant HSHR
|
||||
participant State
|
||||
participant Dispatcher
|
||||
participant Tokio
|
||||
|
||||
Note over HSHR, State: HttpServiceHandlerResponse
|
||||
|
||||
HttpServer-->>HttpServiceHandler: eventually build...
|
||||
alt Protocol::HTTP1
|
||||
HttpServiceHandler->>Dispatcher: H1::Dispatcher::new()
|
||||
HttpServiceHandler->>State: State::H1(Dispatcher)
|
||||
else Protocol::HTTP2
|
||||
HttpServiceHandler->>State: State::H2Handshake
|
||||
end
|
||||
HttpServiceHandler->>HSHR: HttpServiceHandlerResponse::new(State)
|
||||
HttpServiceHandler-->>Tokio: StreamService->Tokio::spawn(HttpServiceHandlerResponse as Future)
|
||||
|
||||
Tokio->>HSHR: poll()
|
||||
alt State::H2Handshake
|
||||
HSHR->>Dispatcher: H2::Dispatcher::new(stream,services)
|
||||
HSHR->>HSHR: poll()
|
||||
else
|
||||
HSHR->>Dispatcher: poll()
|
||||
end
|
||||
Note over Dispatcher: requests loop
|
4
static/img/diagrams/connection_request.svg
Normal file
4
static/img/diagrams/connection_request.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 15 KiB |
34
static/img/diagrams/connection_worker.mmd
Normal file
34
static/img/diagrams/connection_worker.mmd
Normal file
@ -0,0 +1,34 @@
|
||||
sequenceDiagram
|
||||
|
||||
participant ServerBuilder
|
||||
participant WorkerClient
|
||||
participant Worker
|
||||
participant StreamService
|
||||
participant HttpServiceHandler
|
||||
participant Tokio
|
||||
|
||||
ServerBuilder-->>Tokio: spawn(Worker)
|
||||
|
||||
Tokio-->>Worker: poll()
|
||||
alt WorkerState::Available
|
||||
loop
|
||||
Worker->>WorkerClient: rx.poll_next()
|
||||
WorkerClient->>Worker: WorkerCommand(Conn)
|
||||
Worker->>Worker: check_readiness()
|
||||
alt check_readiness() -> Ok(true)
|
||||
Note over Worker,StreamService: Worker::services[Conn.token]
|
||||
Worker-->>StreamService: call(ServerMessage::Connect(stream))
|
||||
StreamService->>HttpServiceHandler: call(stream)
|
||||
HttpServiceHandler->>StreamService: HttpServiceHandlerResponse as Future
|
||||
StreamService->>Tokio: spawn(HttpServiceHandlerResponse)
|
||||
|
||||
else check_readiness() -> Ok(false)
|
||||
Worker-->>Worker: WorkerState::Unavailable
|
||||
else check_readiness() -> Err(token,idx)
|
||||
Worker-->>Worker: WorkerState::Restarting
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Note over HttpServiceHandler: process connection
|
4
static/img/diagrams/connection_worker.svg
Normal file
4
static/img/diagrams/connection_worker.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 16 KiB |
32
static/img/diagrams/http_server.mmd
Normal file
32
static/img/diagrams/http_server.mmd
Normal file
@ -0,0 +1,32 @@
|
||||
sequenceDiagram
|
||||
|
||||
participant HttpServer
|
||||
participant ServerBuilder
|
||||
participant Worker
|
||||
participant StreamNewService
|
||||
participant HttpService
|
||||
participant HttpServiceResponse
|
||||
participant Tokio
|
||||
|
||||
|
||||
HttpServer-->>HttpService: build...
|
||||
HttpServer->>ServerBuilder: listen(addr,Fn->HttpService)
|
||||
ServerBuilder->>StreamNewService: create(addr,Fn->HttpService)
|
||||
HttpServer->>ServerBuilder: start()
|
||||
ServerBuilder->>Worker: start(StreamNewService)
|
||||
|
||||
Worker->>StreamNewService: InternalServiceFactory::create()
|
||||
StreamNewService->>HttpService: new_service()
|
||||
HttpService->>HttpServiceResponse: HttpServiceResponse::new()
|
||||
HttpService->>StreamNewService: HttpServiceResponse as Future
|
||||
StreamNewService->>Worker: StreamService(HttpServiceResponse) as Future
|
||||
Worker-->>Tokio: spawn(StreamService(HttpServiceResponse)).map(Worker))
|
||||
Tokio-->>HttpServiceResponse: poll()
|
||||
HttpServiceResponse-->>Tokio: Ready(Worker(HttpServiceHandler))
|
||||
|
||||
loop Worker process messages
|
||||
Tokio-->>Worker: poll->Pending...
|
||||
activate Worker
|
||||
Note over Worker: pull messages
|
||||
deactivate Worker
|
||||
end
|
4
static/img/diagrams/http_server.svg
Normal file
4
static/img/diagrams/http_server.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 16 KiB |
Loading…
Reference in New Issue
Block a user