code-immersion software overview (part 2) — architecture

October 8, 2009
by Ian McEwen (ihm08)

This post will talk about the general architecture of the code-immersion system. That is, it will give a general idea of how all the parts interact with each other, which should elucidate how the entire system works.

The three main parts of the system are,, and; other files are either conceptually “above” this, making the software easier to use, or “below” this, providing functionality which these three major files use.

  • defines the server, which listens for input. It can deal with input of a few varieties:
    1. Registration: If sent a proper sort of message (this would be by a daemon), the server will add a connection to a specific daemon to its list of locations to dispatch text and code to.
    2. Text and code to be dispatched: From a client, the server can receive text and code to dispatch out to the list of daemons which it has accumulated.
  • defines the daemon, which listens for input of different sorts.
    1. The daemon registers with a server (generally, configured by way of After this, it receives input from the server when it dispatches text and code. The daemon puts this text and code into a datastore.
    2. It also listens for input from clients; these constitute requests for text and code sent by others, which the daemon can then fetch from its datastore and send out. Alongside this the daemon also listens for requests for administrative things, such as reregistering with the server.
  • does everything which a user actually uses to interact. Primarily, this consists of convenience functions which send things to the server and daemon and do various things with the response. The most-used level of these functions is documented in the (help) function of itself; these are all the functions for viewing and running text and code, listing users, reregistering, and so forth. There also exist lower-level functions which these build upon:
    1. At the root is a (send-to) function.
    2. On top of this are built (send-to-server) and (send-to-daemon)
    3. On top of these are built (send-code), (send-message), (request-code), and (request-message).
    4. On top of the request functions are built (display-message), (display-code), (evaluate-code), and (evaluate-list).
    5. Finally, on top of these are built most of the functions defined in (help).
    6. (run), (users), and (reregister) are notable in that they are built on lower-level functions; (run) is built on (request-code) rather than (evaluate-code) and (evaluate-list), while (users) and (reregister) are built on (send-to-daemon), there being no intermediate functions relating to their purpose.

    Note that some of these functions aren’t actually used at the top level; these might be useful for tweaking or extension of the system, however, so they are left in. Note that the top level of functions does not have hyphens; lower levels all do. This helps distinguish among the levels.

Below these three, there lie several files.

  • is an example and template for, which is the file the three above files and several of the low-level files read in for basic options: the user’s name, the locations of the server and daemon and the ports they use, the type of datastore, and the way to print things like text and code.
  • defines different sorts of datastores. Right now, it only defines a hashtable datastore and has an aborted attempt at a list datastore — but, it could easily be extended to other types of datastore, like the list datastore or persistent forms such as a text file or an SQL database. These would then be enabled by way of the configuration file.
  • has a few functions which are shared among the three main files. It defines the listening-and-verifying loop which is at the core of both the server and the daemon, provides a data-verification function for things which are sent through the system (which the aforementioned loop uses), something which formats any valid message in a better-looking way (using the configuration parameter I mentioned above), and finally something which prints the source of the entire package (which is used by some functions which return that source, a requirement of AGPL compliance).,, and are all negligible; they are ways of calling the three main files which don’t require as much futzing-around with configuration files nor actual explicit starting of procedures. The starts of the first two create a and then start the server or daemon; the third just uses (require …) to import the definitions from for use.
As always: if you have questions, comments, or really anything at all, put it in the comments section below.


Leave a Reply

You must be logged in to post a comment.