Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,70 @@ make ci

---

# Laminar Runtime Architecture Diagram

```mermaid
flowchart TD

A["Arc&lt;RwLock&lt;AppState&gt;&gt;<br/><br/>Global shared runtime container"]

A --> B["AppState<br/><br/>Fields:<br/>- upstreams"]

B --> C["UpstreamPool<br/><br/>Fields:<br/>- id<br/>- current_index<br/>- backends"]

C --> D["AtomicUsize<br/><br/>Round robin index"]

C --> E["Vec Arc BackendState<br/><br/>Shared backend objects"]

E --> F["Arc BackendState<br/><br/>Reference counted backend state"]

F --> G["BackendState<br/><br/>Fields:<br/>- config<br/>- healthy<br/>- active_connections<br/>- failed_health_checks"]

G --> H["BackendServerConfig<br/><br/>Static backend configuration"]

G --> I["AtomicBool healthy<br/><br/>Backend health state"]

G --> J["AtomicUsize active_connections<br/><br/>Tracks active connections"]

K["TCP Proxy Task<br/><br/>Accepts client connections"]

K --> L["next_backend<br/><br/>Selects healthy backend"]

L --> F

K --> M["ConnectionGuard new<br/><br/>Starts connection tracking"]

M --> N["ConnectionGuard<br/><br/>Owns backend Arc"]

N --> J

N --> O["Drop implementation<br/><br/>Decrements connection count"]

P["Background Health Checker Task"]

P --> Q["check_backend_status<br/><br/>TCP health probe"]

Q --> I

R["Future Systems<br/><br/>Metrics<br/>Retries<br/>Least connections"]

R --> F
```

# Runtime Flow Summary

1. Client connects to Laminar TCP proxy.
2. Proxy task accesses shared AppState.
3. next_backend() selects a healthy backend.
4. Backend Arc is cloned and moved into ConnectionGuard.
5. ConnectionGuard increments active_connections.
6. TCP traffic is proxied between client and backend.
7. When connection ends, ConnectionGuard drops automatically.
8. active_connections is decremented safely.
9. Background health checker continuously updates backend health state.

---

# CI Policy

All pull requests must pass CI before merging.
Expand Down
4 changes: 2 additions & 2 deletions src/proxy/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub async fn start_tcp_proxy(address: &str, state: SharedAppState) -> anyhow::Re

info!("new client connected {}", client_address);
let state = state.clone();

// Arc<RwLock<AppState>> means SharedAppState only
tokio::spawn(async move {
if let Err(error) = handle_connection(client_stream, state).await {
error!("connection handling failed {:?}", error)
Expand All @@ -32,7 +32,7 @@ async fn handle_connection(mut stream: TcpStream, state: SharedAppState) -> anyh
let state = state.read().await;
let upstream = &state.upstreams[0];
let backend_arc = match upstream.next_backend() {
Some(backend) => backend.clone(),
Some(backend) => backend,
None => {
error!("no healthy backend available");
return Ok(());
Expand Down
Loading