{"id":50478323,"url":"https://github.com/vmarlier/flowstate","last_synced_at":"2026-06-01T15:03:59.246Z","repository":{"id":355391188,"uuid":"1226832204","full_name":"vmarlier/FlowState","owner":"vmarlier","description":"FlowState is a dynamic L7 Reverse Proxy built in Go using only the stdlib.","archived":false,"fork":false,"pushed_at":"2026-05-03T10:59:24.000Z","size":17,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T12:29:46.000Z","etag":null,"topics":["golang","learning-by-doing","reverse-proxy","stdlib-only"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vmarlier.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-01T22:04:47.000Z","updated_at":"2026-05-02T18:38:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vmarlier/FlowState","commit_stats":null,"previous_names":["vmarlier/flowstate"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/vmarlier/FlowState","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmarlier%2FFlowState","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmarlier%2FFlowState/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmarlier%2FFlowState/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmarlier%2FFlowState/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vmarlier","download_url":"https://codeload.github.com/vmarlier/FlowState/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmarlier%2FFlowState/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33780090,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","learning-by-doing","reverse-proxy","stdlib-only"],"created_at":"2026-06-01T15:03:58.113Z","updated_at":"2026-06-01T15:03:59.230Z","avatar_url":"https://github.com/vmarlier.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FlowState\n\u003csup\u003eGolang stdlib-only\u003c/sup\u003e\n\n\u003e [!NOTE]\n\u003e Constraint: This project strictly uses the Go Standard Library. No external dependencies are permitted, ensuring a deep dive into core system engineering principles and the Go runtime.\n\nFlowState is a dynamic L7 Reverse Proxy built in Go using only the stdlib.\n\n## Idea\n\n### Design goals\n\n- Build a **stdlib-only Layer 7 reverse proxy** to understand HTTP internals, connection reuse, and request lifecycle.\n- Implement **explicit routing, backend selection, and middleware composition** without framework abstractions.\n- Make **timeouts, cancellation, health state, and observability** first-class so behavior under failure is understandable.\n- Favor **clear control flow and measurable correctness** over feature count.\n\n### Non-goals\n\n- Not a production replacement for Envoy, NGINX, or Traefik.\n- No dynamic control plane, distributed config, or service discovery at first.\n- No HTTP/3, gRPC-native balancing, or WASM/plugin ecosystem.\n- No external metrics/tracing libraries.\n\n### Architecture\n\n- Ingress path: `net/http` server accepts request.\n- Router: matches host/path/method to a route entry.\n- Middleware chain: request ID, logging, rate limiting, recovery, optional auth later.\n- Load balancer: selects a healthy backend for the route.\n- Proxy layer: rewrites request, injects forwarding headers, strips hop-by-hop headers, forwards via custom `http.RoundTripper`.\n- Health subsystem: active probes + passive failure observation update backend state.\n- Metrics/admin endpoints: expose counters, latency buckets, backend health.\n\nInternal flow: `server -\u003e router -\u003e middleware -\u003e lb -\u003e proxy transport -\u003e response filters -\u003e metrics`\n\n### Failure model\n\n- If a backend times out, connection fails, or returns repeated 5xx responses, it may be marked unhealthy and removed from rotation.\n- If all backends are unavailable, return `502` or `503` consistently.\n- Client cancellation propagates to backend requests through `context.Context`.\n- On shutdown, stop accepting new requests and allow in-flight requests to drain for a bounded time.\n- No guarantee of zero request loss during process crash or forced termination.\n\n### Benchmark plan\n\nMeasure with `testing.B`, `httptest`, and simple load tools.\n- Requests/sec through proxy with 1, 10, 100 concurrent clients.\n- Latency: p50/p95/p99 under healthy backends.\n- Tail latency under one slow backend.\n- Cost of middleware stack.\n- Effect of connection reuse vs disabled keep-alive.\n- Load-balancer distribution fairness across backends.\n\n### Test strategy\n\n- Unit tests for router matching, backend selection, health transitions, middleware behavior.\n- `httptest.Server` integration tests for end-to-end proxying.\n- Timeout/cancellation tests with slow handlers and canceled contexts.\n- Race-detector runs for backend state, counters, and health updates.\n- Fuzz tests for route parsing, config parsing, and header rewriting.\n- Deterministic failure injection for connection errors and backend flapping.\n\n---\n\n### Core (v0.1)\n\n- [X] **Static config loader**\n  - Use: `encoding/json` or `encoding/gob`/custom parser, `os`, `flag`\n  - Learn: config modeling, validation, immutable runtime config\n- [ ] **HTTP server bootstrap**\n  - Use: `net/http`, `context`, `os/signal`\n  - Learn: server lifecycle, graceful shutdown, deadline propagation\n- [ ] **Basic route matching**\n  - Start simple: exact path + prefix match, host/method aware\n  - Use: slices/maps, longest-prefix match\n  - Learn: request dispatch, matching semantics\n- [ ] **Custom reverse proxy path**\n  - Use: `net/http`, `net/url`, `io`, custom handler instead of magic wrappers\n  - Learn: request cloning, upstream URL rewriting, response copying\n- [ ] **Custom transport**\n  - Use: `http.Transport`\n  - Learn: keep-alives, `MaxIdleConns`, `MaxIdleConnsPerHost`, dial timeout, TLS handshake timeout, response header timeout\n- [ ] **Forwarding and hop-by-hop header handling**\n  - Learn: `X-Forwarded-For`, `X-Forwarded-Proto`, RFC hop-by-hop header stripping\n- [ ] **Weighted round robin**\n  - Learn: stateful load balancing, atomic counters vs mutexes, fairness\n\n### Correct (v1.0)\n\n- [ ] **Request-scoped context and timeouts**\n  - Use: `context.WithTimeout`\n  - Learn: cancellation propagation, bounded resource usage\n- [ ] **Structured logging**\n  - Use: `log/slog`\n  - Learn: request lifecycle logging, correlation IDs\n- [ ] **Request ID middleware**\n  - Use: headers + context values\n  - Learn: cross-cutting concerns, observability basics\n- [ ] **Recovery middleware**\n  - Use: `defer`, `recover`\n  - Learn: panic boundaries in servers\n- [ ] **Active health checks**\n  - Use: `time.Ticker`, `net/http` or `net.DialTimeout`\n  - Learn: health probe design, state transitions\n- [ ] **Passive health checks**\n  - Learn: consecutive failure counting, decay/reset, backend ejection\n- [ ] **Consistent unhealthy-backend policy**\n  - Learn: fail-open vs fail-closed, cooldowns\n- [ ] **Graceful shutdown and backend draining**\n  - Use: `http.Server.Shutdown`\n  - Learn: lifecycle management under load\n- [ ] **Metrics endpoint**\n  - Use: `expvar` or custom text format via `net/http`\n  - Learn: counters, gauges, latency buckets\n\n### Performance (v1.1)\n\n- [ ] **Trie router only if route count justifies it**\n  - Learn: radix tree / trie, path parameter trade-offs\n- [ ] **Power of Two Choices**\n  - Learn: queue-aware balancing, herd effect mitigation\n- [ ] **Token bucket rate limiter**\n  - Use: `time`, `sync`, monotonic refill math\n  - Learn: admission control, backpressure\n- [ ] **Connection pool tuning benchmarks**\n  - Learn: transport tuning under concurrency\n- [ ] **Latency histograms / approximate percentiles**\n  - Learn: buckets vs exact percentiles, tail latency measurement\n- [ ] **Zero-allocation hot-path cleanup where useful**\n  - Learn: buffer reuse, avoiding needless header/value copies\n\n### Advanced (v2.0)\n\n- [ ] **Circuit breaker**\n  - Learn: closed/open/half-open FSM, rolling failure windows\n- [ ] **Hot config reload**\n  - Use: atomic config swap, signal-driven reload\n  - Learn: read-copy-update style config management\n- [ ] **Per-route middleware policies**\n  - Learn: policy composition and precedence\n- [ ] **Retry policy for idempotent requests only**\n  - Learn: retry safety, duplicate side effects\n- [ ] **Outlier detection**\n  - Learn: passive latency/error-based backend suppression\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvmarlier%2Fflowstate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvmarlier%2Fflowstate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvmarlier%2Fflowstate/lists"}