Adapters
An adapter is how Ezu boots your app and asks it questions, so the core never learns what Rails is. Each slot gets its own adapter instance, with its own working directory, port and clock.
After reading this page, you will know:
- What every adapter answers.
- What the Rails adapter does, and its options.
- How to map an app that isn't Rails.
The interface
| Method | Answers |
|---|---|
prepare |
Make a throwaway copy of the app, once per run. |
prepare_from(prepared) |
Copy that for one slot. |
routes |
Every GET route: {path, regexp, page_id}. |
translations(locales) |
Every translation, as flat dotted keys per locale. |
seed(script, slot) |
Run the seed for one slot and return its JSON. |
start / stop / base_url |
The slot's server. |
blocked / hidden |
URL globs to abort, and CSS selectors to hide, such as development tools. |
Rails
adapter :rails,
prepare: %w[db:schema:load tailwindcss:build], # rails tasks run once, before the slots
env: { "WARIWARI_RELEASE_ID" => "atlas" }, # extra environment for every process
health_path: "/up" # answers 200 once the server is up
What it does:
- Runs every process with
RAILS_ENV=developmentandDATABASE_URLpointing at a SQLite file intmp/ezu-work/, so the app's own databases are never touched.prepareloads the schema there, and each slot gets a copy. - Reads routes with
bin/rails runner: GET routes for HTML, namedcontroller#action. - Reads translations from
I18n. - Runs
ezu/seed.rbwithbin/rails runner, withEZU_SEED_OUT,EZU_SLOTS,EZU_LOCALEandEZU_VIEWPORTset. - Starts
bin/rails serveron the slot's port. - Preloads
repeatable.rbinto every process throughRUBYOPT:Time.nowreads Ezu's clock file, andSecureRandom,rand,sampleandshuffledraw from seeded sequences. See Repeatable runs. - Blocks the mini-profiler and Tensaku's event stream, and hides Tensaku's button, so development tools never land in a screenshot.
A docs site with no database, like this one, passes prepare: %w[tailwindcss:build] and health_path: "/".
Command
For any app started by a shell command:
adapter :command,
start: "exec ruby server.rb", # must listen on $PORT
routes: "routes.json", # [{ "path": "/items/:id", "page_id": "items#show" }]
translations: "translations.json", # { "en": { "items.details": "Details" } }
seed: "bin/seed", # writes JSON keyed by slot name to $EZU_SEED_OUT
health_path: "/health",
hidden: [ "dev-tool" ]
The app gets PORT, EZU_CLOCK_FILE and EZU_RANDOM_SEED, and is only repeatable if it honours them: read the time from the clock file, and seed its randomness. Ezu's own end-to-end test maps a tiny app this way, in test/fixtures/app/.