Rho language and toolchain
A systems programming language and its toolchain: the compiler, the standard library, the module registry, and the tools that build, document, test and debug a project.
Start here
Recent releases
Telemetry is now a toolchain feature rather than an application convention.
- `sql_exec_many` runs one prepared statement once per row in a single transaction, so a service can write a batch instead of committing every row. The sql port now writes its affected count through the out-parameter instead of into a copy, and no longer takes the handle-table lock twice in a statement. - The `telemetry` port ingests a gateway's sequenced outbox into a project's store: it polls the outbox, writes a page in one transaction, serves latest and time-range queries, and rolls completed minutes and hours up before retention. A service can serve latest and series over the schema its project declares. - The gateway port lists the generic sensor fields a firmware publishes, so a listing carries every `m<index>.<field>` a board reports, and records sensor frames in its history. - The telemetry port excludes fault readings from latest values, rollups and series, walks a JSON path for HTTP device descriptors, applies the descriptor's scale before storing the value, and records a reading a service read itself. - The gateway port also sends a gateway bearer token when the deployment names one.
The documentation site image is now a multi-stage build: the live docsite service runs in a Go builder and is mirrored into static pages, so the runtime is a slim static server with the same landing page, menu, release notes and generated documentation as before.
Release notes on the documentation site preserve changelog paragraph breaks instead of flattening a release into one block.
Generated servers can carry an `auth` middleware: ES256 session cookies verified with a pinned public key, direct and reverse-proxy origins, one-use login tickets, local sessions, and HTTPS-aware cookies. `rho auth` gained `keygen`, `ticket` and `verify`, and generated responses can carry headers, which is what lets a login set a cookie and redirect.
A module manifest may declare the plugins an application loads:
```yaml plugins: - name: alert-log enabled: true config: path: alert.log - name: email-alert enabled: false config: to_address: ops@example.internal ```
The list is validated: a plugin needs a name, `enabled` is a decision rather than a word, and `config` is a map whose keys belong to the plugin. The schema says what an application asks for; the plugin registry and its manager are the application's own.
The Go backend also learned two shapes the expenses module needs: a fixed-size array parameter is emitted with one dimension rather than two, and a `Ptr[T]` built from a reference carries the address in the field the generated struct has. Both have tests in `src/codegen/goexpr_test.go`.
The SQL port now splits a schema on statement boundaries that respect line and block comments as well as string literals, so a semicolon in a comment does not end a statement early. The version stays 0.1.4; the binary is rebuilt from the same source.
The documentation site lists the newest release first, so its overview shows the current version rather than the first four releases ever written.
The gateway port provides `gateway_http_get` and `gateway_http_post`, the HTTP requests a gateway needs to poll and switch a network device.
A generated service can stream a file as Server-Sent Events with `web.http.sse_file`. Each line is one event, a `__DONE__:<status>` line closes the stream with a `done` event, and the stream follows a file that is still being written. The generated Go server keeps the connection open for the length of the action and sends keepalives; a long build or flash no longer trips a write deadline, and the read deadline no longer closes a stream after a minute.
The `gateway` port gains `gateway_wall_time_ms`, the host's Unix time in milliseconds. A node's `timestamp_ms` is its own uptime; a gateway can now also record when it received the frame, which is what places a reading on a calendar.
Module manifests may declare `capabilities` and `deployment`. A board says which roles it can take (`gateway`, `relay`, `node`, `edge`, `host`), what it has (`wireless`, `ethernet`, `links`, `buses`, `deploy`), and how a deployment reaches it (`method`, `arch`, `kconfig`, `apps_dir`). A driver says it is a sensor, its bus and what it measures, and names the example, image, Kconfig and boards a deployment builds. The module schema validates these blocks, including `board.summary`; the keeper's deployment wizard has a schema of its own.
A generated Go runtime emitted `rhoGetenv` twice when a program read an environment variable, which was a redeclaration in the generated runtime. It is emitted once now, and a test holds it.