Friday, August 04, 2006

Factor web framework

I'm working on a new web framework for Factor. My plan is to have web applications built as a collection of concurrent processes running on the server and the client browser. Processes on the server can send messages to the browser (using a 'comet' style connection) and vice versa.

Client processes are implemented using the lightweight concurrency system I built using Narrative Javascript. An example process that runs on the browser looks like:
function alerter() {
while(true) {
var msg = receive->();
document.getElementById("messages").value += (msg + "\n")
}
}
register_process("p1", spawn(alerter));

This spawns a process named in the registry as 'p1'. It blocks waiting for a message. When one is received it will add the message string to an text area with the Id 'messages' and then resume waiting.

The message can come from other client side processes or from the server if a comet connection is established. From the Factor server you can get access to the client side process with 'get-process-on-page'. Each page connected to the server has an 'id'. 'get-process-on-page' takes this id and returns a process which can be used to send messages to the client process:
"1234" "p1" get-process-on-page "Hello" over send "World" over send

This example gets the 'p1' process on the client with the id '1234' and sends it two messages. One 'hello' and then 'world'. These will result in the 'p1' process shown above running on the browser waking up and adding the text to the textarea.

Most Factor objects can be sent as messages and they are serialised to JSON when sent to the client. I'm currently writing a JSON parser for Factor which will allow client processes to send messages to server processes.

The framework so far works up to this point and runs on Opera, Safari, Firefox and Internet Explorer. Once the JSON parser is written and working I'll make the code available.

I'm keen to see how this style of web programming compares to continuation based web servers, and how they can be combined (using cont-responder in Factor). I hope to also write other back ends (Scala, Erlang, etc) to compare the different technologies.

Categories: , ,

3 Comments:

Anonymous Dan Mayernik said...

Is the framework really multi-threaded? I mean, when you say multiple processes do you mean in multiple threads too? Because as far as I know, most modern browsers only support one thread for javascript processing. Please explain...

5:17 PM  
Anonymous Sébastien said...

This is most probably base on the already lightweight (application-level) "threading" made by browsers.

The JavaScript interpreter is single-threaded, but the HTTP request are made in their own thread, then the callbacks are queued within the JS interpreter.

So you can actually use the HTTPRequest object to simulate a yield that resumes upon request data arrival.

Well... this may be a bit complicated ;)

3:54 PM  
Blogger Chris Double said...

It is non-preemptive multi-threading, otherwise known as cooperative threads.

The original javascript is transformed into continuation passing style. I wrote a thread scheduler that takes uses these continuations to implement multi threading.

Whenever a thread yields by calling a specific function to do that, or blocks in some manner (waiting for an xmlhttp request, settimeout, button click, etc) control transfers to the next thread in the scheduler.

For an example see my light weight threads example which shows two threads updating divs on the page.

To 'yield' processing to the browser I periodically call 'settimeout' passing it the schedulers next thread to run so the script does not cause the browser to display the 'script is running wild' error message.

Although it sounds complex it works very seamlessly.

5:41 PM  

Post a Comment

<< Home