Progress Update #0 - 2023 07-14

We will begin posting regular updates here from now on. These updates will cover a wide range of technical topics, including user-facing features and underlying technology. Stay tuned!

This week I'm most excited about two new systems: exit nodes and the program replayer.

Personal Exit Nodes

Users are finally able to run their own private HTTP exit nodes and route outgoing traffic through it. Only one exit node per account is supported at the moment and traffic from all programs will go through it. We do plan to have more granularity in the future so that specific programs can be routed via specific exit nodes.

Running your own exit node is easy:

$ mctl exit-node

Membrane will continue to route outgoing traffic through it as long as its running. It's the type of thing you'd run as a launchctl/systemctl daemon on a home server.

Additionally, you can pass a transformer script

$ mctl exit-node --transformer ./transformer.js

Which receives the outgoing request as stdin and outputs a potentially modified one to stdout. This can be used to, for example, privately inject credentials.

We plan to expand exit nodes with supporot for credential insertion and other fun features.

Program Replays

This is a big one. Membrane can now replay programs! A replay re-executes everything that happened to a program, but instead of doing actual I/O, responses from the original run are injected by the system. This is all thanks to the write-ahead-log architecture and our deterministic JS engine. Replays will be a core Membrane system moving forward, for multiple reasons:

The first and most obvious one is Time-Travel Debugging. We want to be able to go to any point in the program's past and replay events with the debugger attached. This should make the debugging experience incredibly powerful.

Another less obvious yet more important reason is that Membrane snapshots not only the JS heap but also the heap of the JS runtime itself. When the runtime needs to be updated, this situation becomes a problem. How do you patch a running program?

The answer is: by replaying it! We can now re-run a program from start to finish, including all queries, actions, events, etc, on a different (improved) JS runtime. One caveat is that replays are O(N) operations where N is the number of events in the log, in some cases it can take a while, that's why they run on separate processes as to not interrupt the original program. Once the replay finishes and consistency checks pass, the old snapshot is swapped with the new one voila! It's now running on a new runtime.

There are other fun and creative uses for replays we'll be discussing in the future but do let us know if you have ideas!

Until next time!