Skip to content

Remote Compilation

Mike Fikes edited this page Apr 21, 2015 · 15 revisions

The initial approach to running in the simulator involved a simple and satisfactory ClojureScript compilation pipeline as illustrated here:

However when running on an actual device we want to support all REPL interactions including those that today drive incremental compilation (think :reload and :reload-all).

Architecture

In a typical workflow we imagine a user has compiled all of his dev time files including source maps, analysis caching, ClojureScript sources copied out of JARs, generated JavaScript etc. into an :output-dir. For the simplest most straightforward approach that replicates the setup of the simulator this :output-dir should be copied into the application's bundle.

However this leave's the open question, what happens when you connect a REPL to a remote device?

WebDAV

The ClojureScript compiler compiles to :output-dir in only a few key places. There is in fact no requirement that :output-dir be local to the development machine. :output-dir could in fact be a WebDAV server running on the device itself. When connecting a REPL to the running application we could use PROPFIND to get the current directory structure. Once we have that we can treat the WebDAV server as a simple remote file system - instead of worrying about synchronization between local compiled state and remote compiled state, we can simply read everything off the device - source maps, analysis caches, etc. When compilation is triggered we can simply PUT and so on.

The WebDAV-based architecture is illustrated here:

Client

There are many possible routes to go with WebDAV clients. I've looked at Apache Jackrabbit, Sardine, Milton, http-kit, clj-http, and Apache HttpComponent.

  • Jackrabbit is far too wide in scope (a compliant JCR implementation)
  • Sardine is small and written over Apache HttpComponent, but an extra dependency
  • Milton has licensing issues
  • http-kit, has no dependencies but this is a liability more than a benefit
  • clj-http has numerous dependencies, also written over Apache HttpComponent
  • Apache HttpComponent is simple, well maintained and we only need a small bit of functionality

Of these options going with plain Apache HttpComponent will likely provide the least amount of hassle in the long run.

Note: For now, OS X is used as a WebDAV client, and the Ambly REPL causes OS X to mount the target WebDAV directory under /Volumes. This short-circuits the need to revise the compiler; we simply dynamically set :output-dir to the correct mount point on the filesystem.

Server

GCDWebServer is a GCD based WebServer that ships with WebDAV support. It is installable via CocoaPods. The project seems active and well maintained and my experience with it so far has been positive. It just works as advertised.

Bonjour (MDNS)

By leveraging MDNS (aka ZeroConf/Bonjour) we can make the REPL workflow likely better than the one offered by regular ClojureScript REPLs. MDNS would allow us to automatically connect both the REPL as well as the WebDAV connection.