Binding JavaScript to Self

For those who stumble on this post with no context, Self is an object oriented programming language by Randy Smith and David Ungar. It is a true object oriented (by Kay's definition), prototypal, message passing language with a networked graphical programming environment in which multiple developers can edit live objects. Work on the language was mostly sponsored by Sun but ended largely when Sun released Java and reassigned most of the VM team to fix the slowness of the early Java VM. Self was the basis of both the JavaScript object model and the Hotspot JVM. It is probably the most important software system most programmers have never seen.

In the Self image, it like it's progenetor Smalltalk is imaged based, there exists a proof of concept remote interface called socketServer. When socketServer is running, you can connect via telnet to the specified port and execute Self code via a simple commandline with history. Since the feed is just line based it is actually trivial to modify this to process incoming HTTP requests and execute a script that is contained in the body of the post. This was sufficient inspiration for my next idea which was "why not make a Self interface in a browser running JavaScript? The LivelyKernel has already implemented Morphic in JavaScript + SVG (the GUI object system the Self UI is built in) so it can't be too hard to port the Self interface to JavaScript and simply have each language pass messages to objects in the other. Self already has transparent proxy objects for native functions and external objects, so it should simply be a matter of having JavaScript pass the right code back to socketServer.

Now the trick is that this relationship goes both ways. Self needs to informthe GUI to update. Playing with mirrors and the GUI itself you'll notice that the whole system benefits from messaging which updates a wide variety of values. Inspect the properties of an object in the GUI and in real time you can see the values update as you send messages to objects. Fire off some invalid message and the live debugger will let you step through and correct your code in context. The notions of immediacy and direct manipulation are lost if the Self VM can't notify the UI of changes. On those few browsers where WebSockets are available we can use them. On browsers where they aren't we can fake them with a little bit of Flash and bridge the socket layer with some ActionScript. Now all we need is a good way to secure the communication between client and server.

Enter X-Magic-Cookie: Assuming that we are going to connect to the Self server image via SSL, we can use a simple SHA256 hashed password for authentication, and rely upon a magic cookie for session handling in case we need to reconnect and redraft a connection. Since we can't guarantee that the client will have a persistent connection in the case of mobile applications like an iPad on 3G, this will be sufficient for resuming a broken connection. We may want the server side to periodically update the shared secret but that can wait until the rest is working.

The final bit is making distributed message sends transparent to the programmer. With a web based interface replacing the X windows UI, we can easily run the VM on a headless node in the cloud. By tweaking a minimal Linux image, and having init directly spawn the VM, we can effectively boot directly into Self. Using a post startup script, we can insure that the image comes right back up with the socketServer running, as well as, a HTTP/1.1 interface for providing the static content necessary to make the web based UI work. Since Self can spawn multiple processes as well as run green threads, we can use it to setup any additional daemons and processes we'd find useful in the base system. The only thing we'd need init to do is setup some ptys so we can fire up additional VMs. If we create 4 VMs per system: admin, dev, staging, and production. Since we can save a snapshot at anytime, we can have images in various states of readiness and continue to test our Ganges without blocking ongoing development. If the massages can be distributed without the programmer having to honk about it, we can have applications send messages to more than one VM at a time and be able to keep staging and production in sync. It also allows us to evaluate the performance and stability under production load. The flip side is that we need to be smart about how we deal with responses from multiple environments. But for backend services like KV stores, DBIs, and the like, message replication can be a valuable tool.

Towards these ends I've started writing glue for libevent and ømq. The underlying socket code in the Self VM is rather dated as none of the kernel interfaces used in production web servers existed in the mid 90's when this code was written. Updating these bits to take advantage of epoll, kqueue, and the writev iovec capabilities of Linux, Mac OSX, and BSD can dramatically improve the scalability of the system. Based on my experiences with Jawas and the ConnectionServer projects, these system calls can drive upto 6k http requests per second on modern hardware using 66% of the CPU. Relying upon the OS at this level removes most of the application code from the burdern of driving data out the io ports. Managing 10k+ simultaneous connections becomes rather easy for the application code as long as you write your application as an event based statemachine. Self is actually well equipped for this model of programming as these states translate directly into message sends to objects. By mapping read, write, close, and error events directly with messages, the per client thread objects can easily manage complex application state, delegating activity to other objects in their context sandbox.

My eventual goal is to write a Self plugin for Mozilla and Webkit based browsers containing the SelfVM and use the JS/WebGL interface as the programming tool to interact with it. Mixed with a WebGL interface and distributed messaging, Embedded Self would make an ideal platform for building distributed applications. With headless Self VM images running on commodity cloud providers entire new styles of virtual worlds could be built using tools that are open, free, and flexible. Now all I need is a few weeks of free time to finish this up.