feat: middleware examples, golit serve warm path, and SSR benchmarks#7
Merged
Conversation
- Add golit serve subcommand: warm Renderer via GET /health and POST /render - Wire middleware to GOLIT_SERVE_URL (HTTP) with fallback to golit transform exec - Container entrypoints start golit serve; GOLIT_DISABLED skips for bench compare - dev-serve.sh + Makefile serve for local warm path; ignore root binary only (/golit) - Bench scripts: curl metrics, optional Chrome headless; portable stats (no gawk asort) - GOLIT_DISABLED toggle; optional ?bench perf snippet for client metrics - Shared examples/bench/perf-snippet.js reference Made-with: Cursor
Made-with: Cursor
- Capture container memory via podman/docker stats after the curl load - Measure run-to-ready using a static health URL and cold first HTML per endpoint - Document metrics, artifacts, and startup vs steady-state vs prewarm in README Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
Adds warm-path SSR support via a long-lived golit serve HTTP server, plus PHP and Ruby middleware examples (with containers and benchmarking scripts) to demonstrate per-request SSR without batch transforms.
Changes:
- Introduces
golit serve(HTTPGET /health,POST /render) to reuse a warmRendereracross requests. - Adds PHP front-controller and Ruby Rack middleware examples that SSR HTML via
golit serve(or fall back to per-requestgolit transform). - Adds container wiring, benchmark scripts, and documentation updates for the new examples and warm/cold paths.
Reviewed changes
Copilot reviewed 33 out of 34 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents new middleware examples, golit serve, and benchmark workflow. |
| cmd/golit/main.go | Adds CLI dispatch/help text for the new serve command. |
| cmd/golit/serve.go | Implements the warm SSR HTTP server around a long-lived Renderer. |
| .gitignore | Stops ignoring cmd/golit/* by only ignoring the root /golit binary. |
| examples/bench/perf-snippet.js | Adds a Performance API snippet for optional browser-based benchmark metrics. |
| examples/php-middleware/Makefile | Adds build/serve/container/bench targets for PHP middleware demo. |
| examples/php-middleware/package.json | Adds Lit dependency for the PHP demo component. |
| examples/php-middleware/golit.yaml | Adds local transform config pointing at bundles/. |
| examples/php-middleware/.gitignore | Ignores bundles/node_modules/bench results for PHP demo. |
| examples/php-middleware/components/my-counter.js | Adds the demo Lit <my-counter> component. |
| examples/php-middleware/public/router.php | Implements PHP front controller and SSR middleware (warm serve or cold transform). |
| examples/php-middleware/public/pages/_layout.php | Adds shared HTML layout, import map, and optional perf instrumentation. |
| examples/php-middleware/public/pages/home.php | Adds PHP demo home page with <my-counter>. |
| examples/php-middleware/public/pages/about.php | Adds PHP demo about page explaining the SSR pipeline. |
| examples/php-middleware/dev-serve.sh | Starts golit serve locally before running PHP (warm path). |
| examples/php-middleware/docker-entrypoint.sh | Starts golit serve in container unless SSR is disabled. |
| examples/php-middleware/Containerfile | Builds a runnable container image for the PHP middleware demo. |
| examples/php-middleware/bench.sh | Benchmarks container startup/TTFB/size/memory with SSR on vs off. |
| examples/ruby-middleware/Makefile | Adds build/serve/container/bench targets for Ruby middleware demo. |
| examples/ruby-middleware/package.json | Adds Lit dependency for the Ruby demo component. |
| examples/ruby-middleware/golit.yaml | Adds local transform config pointing at bundles/. |
| examples/ruby-middleware/.gitignore | Ignores bundles/node_modules/bench results and Gemfile.lock for Ruby demo. |
| examples/ruby-middleware/Gemfile | Adds Rack/Puma dependencies for the Ruby demo. |
| examples/ruby-middleware/config.ru | Adds a minimal Rack app and mounts the SSR middleware. |
| examples/ruby-middleware/lib/golit_middleware.rb | Implements Rack middleware for warm serve / cold transform SSR. |
| examples/ruby-middleware/views/layout.erb | Adds shared HTML layout, import map, and optional perf instrumentation. |
| examples/ruby-middleware/views/home.erb | Adds Ruby demo home page with <my-counter>. |
| examples/ruby-middleware/views/about.erb | Adds Ruby demo about page explaining the SSR pipeline. |
| examples/ruby-middleware/components/my-counter.js | Adds the demo Lit <my-counter> component. |
| examples/ruby-middleware/dev-serve.sh | Starts golit serve locally before running rackup (warm path). |
| examples/ruby-middleware/docker-entrypoint.sh | Starts golit serve in container unless SSR is disabled. |
| examples/ruby-middleware/Containerfile | Builds a runnable container image for the Ruby middleware demo. |
| examples/ruby-middleware/bench.sh | Benchmarks container startup/TTFB/size/memory with SSR on vs off. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Use case-insensitive lookup for Content-Type so SSR is not skipped when apps use mixed-case keys. Replace Content-Length without leaving duplicate header names. Made-with: Cursor
Made-with: Cursor
Handle glob() false, unlink only files, and rmdir only when the directory exists. Made-with: Cursor
Fail entrypoint on /health timeout, kill the background golit process, and avoid exporting GOLIT_SERVE_URL. Applied to PHP and Ruby docker-entrypoint.sh. Made-with: Cursor
Exit before exporting GOLIT_SERVE_URL; EXIT trap still kills golit serve. Made-with: Cursor
Ensure r.Body is closed on every return path from POST /render. Made-with: Cursor
Detect OCI binary once (CTR), use for run/rm/stats, fail if neither is on PATH. Pass CONTAINER_RUNTIME to make container so image build matches the bench runtime. Made-with: Cursor
Default podman; override with CONTAINER_RUNTIME=docker for container and container-run targets. Made-with: Cursor
Clarify bench.sh engine detection, make container CONTAINER_RUNTIME override, and generic container run/stats wording. Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds PHP and Rack middleware examples that SSR Lit via golit, a long-lived
golit servecommand for a warmRenderer, container/local wiring, and benchmark scripts.Changes
golit serve:GET /health,POST /render(full HTML → transformed HTML), mutex aroundRenderHTML, graceful shutdown.GOLIT_SERVE_URLuses HTTP to the warm server; unset falls back to per-requestgolit transformexec.docker-entrypoint.shstartsgolit serveunlessGOLIT_DISABLED(used by bench for with/without compare).bench.sh+ Make targets; curl TTFB/size; optional--browser/--trace; macOS-friendly stats (no gawkasort)..gitignore: ignore root binary as/golitonly socmd/golit/*.gois not ignored.Notes
Rebuild images after merge for warm-path benches (
make container).Made with Cursor