othismo · an image runtime

Objects that only see what you mount.

othismo runs images: sets of sandboxed AssemblyScript objects that reach each other only through the paths in their own namespaces. If the image doesn't put something in an object's view, the object can't reach it.

The image

Everything this server can touch.

The site is an image of its own, which touches nothing on the host: it needs a listener and a console, and the image that runs it gives it the real ones, whose address the deployer can change. Its files are packed into it, and the HTTP server reaches them only through the site controller.

The site also serves a file that exists only in its code. It counts the requests it has forwarded:

–

requests forwarded by the site so far · /hits

needs /net/tcp  Listener
needs /dev/cons Console

instance http : HttpServer {
  bind  /net/tcp  /net/tcp
  bind  /dev/cons /dev/cons
  mount /www pages
}

instance pages : StaticSite {
  mount /files files readonly
}

instance files : PackedFiles { include "./public/" }

mount /http http
write /http/hosts/* "/www"
write /http/hosts/files.localhost "/www/static"
The model

A Plan 9 namespace for every object.

No routing tables and no special syntax for each new kind of connection. Objects send requests to paths, and the image decides what each object can see.

01

Private views

Every instance has its own view: mount points that put another instance's served tree at a path. The image builds it; the instance can rearrange it, but only with names it can already see.

02

Names are the capabilities

A path is resolved in the sender's own view. A name that isn't there is simply not found. Read-only mounts let only safe verbs through, all the way down the chain.

03

The world is a server

The console, TCP and files are servers the runtime implements, given only as the needs of the image being run. They are the only way out, and --check prints them, and the most each object can ever reach.

How this page reached you

One request, four hops.

This site is served by the static example image. Here is what happened when you asked for the design page.

  1. 1

    The listener accepts, http watches

    The listener streamed your connection's name to the HTTP server, which watched /net/tcp/<conn>/data until your whole request had arrived.

  2. 2

    HTTP becomes a namespace request

    GET /docs/ became read /www/docs/ in the server's view, where the image mounted the site. The server knows nothing about files.

  3. 3

    The site forwards

    The site controller added index.html and forwarded the request to /files/docs/index.html in its own view, a read-only mount. It never sees the bytes.

  4. 4

    The packed files answer the caller

    PackedFiles answered with the file's bytes, as text/html, from the files built into the image. The answer went straight back to the HTTP server and out over your connection.

Try it

Serve these docs yourself.

Requires Rust, Node and Task. The site is the docs, rendered.

task run:example:static     # http://127.0.0.1:8080
task build:docs             # re-render the docs into examples/static/public
task build:example:static   # seal it into examples/static/static.rti
task run:example:static -- --set listen=0.0.0.0:8080