1
0
mirror of https://github.com/actix/actix-website synced 2024-11-23 16:31:08 +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:
Maxim Vorobjov 2020-01-28 14:36:35 +03:00 committed by Yuki Okushi
parent 53214f4727
commit c1a8103cbc
14 changed files with 265 additions and 0 deletions

View File

@ -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

View 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

View 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)

View File

@ -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">

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB