Tuesday, May 24th, 2005

JavaScript Threading and Continuations

Category: JavaScript

<p>Coming from a world such as Java, developers sometimes wish they had rich threading constructs. The f(m) project has gone ahead and implemented a threading construct / library for you to use.

Threading is a double edged sword though. It is very easy to shoot yourself in the foot, and it brings in a lot of complexity. This is why many want to stay away from this road.

The HailiWiki folks (clone of TiddlyWiki) have been playing with client-side JavaScript continuations to make the Ajax async programming model better.

If you look at Microsoft’s COmega, you see creative concurrency models that we could learn from too.

Any thoughts on Threading in JavaScript? Have you ever wanted something richer?

Related Content:

Posted by Dion Almaer at 2:42 pm
21 Comments

+++--
3.4 rating from 37 votes

21 Comments »

Comments feed

Hi There,

Thanks for the link.

We’ve been using AJAX for more than 3 years over here. Lot of client side javascript. Sometimes aync calls and sometimes SYNC calls(as in onload() event handlers). This leads to synchronization issues. We’ve always wanted threading support BUT since we did NOT find threading support, we always got around these issues.

If all AJAX(javascript) developers start using these threading (primitives), then web apps will be lot more responsive.

BR,
~A

Comment by Anjan Bacchu — May 24, 2005

This library is a joke. It isn’t possible to do multi-threading in Javascript. The implementation of setTimeout/Interval in modern browsers, which this library uses, does not execute the callback on a separate thread, so you can never have concurrent code executing.

This is just another case of a DHTML/Ajax programmer trying to imitate conventions of more robust programming frameworks for no real gain. Ajax is limited, people, just accept it. Love it for what it is.

I have no desire to insert your giant pile of Javascript into my web pages just to rename a bunch of functions to make them sound cool. If you want “concurrency” just call setTimeout directly and spare your users the download.

Comment by Joe — May 25, 2005

haha!! that was strong XD , but, setTimeout dont runs in other thread, sure??

Comment by JaViS — May 25, 2005

why should setTimeout run in a separate thread? Javascript libraries (and the things they rely on) tend not to be threadsafe, so setTimeout simply pausing execution of other things to get its job done makes complete sense. Regardless, there’s no guarantee that it would be executing from another thread in all interpreters even if it worked this way in one of them since setTimeout and setInterval simply aren’t part of the ECMA 262-3 spec.

As for Joe’s comment about JS trying to “imitate conventions of more robust programming frameworks”, he clearly has no experience in non-deterministic programming environments.

The fact that JS doesn’t express thread-like semantics for concurrency is in no way a liability. Threads (as implemented in most programming languages today) are a pretty poor concurrency primitive. They’re usually expensive and difficult to reason about. Continuations, the big brother of transitive closures, are much more promising since they allow lightweight concurrency without the explicit context management overhead. Better yet, they often don’t require the expense of new stack allocation which is common of thread-style concurrency.

I would encourage Joe to check out things like Twisted Python or Stackless Python which achieve amazing concurrency without needing to resort to threads. Even tools like Capriccio, which emulate thread semantics for backward compatibility, don’t actually use threads under the covers.

Regards

Comment by Alex Russell — May 25, 2005

Alex, you’re misunderstanding me. I’m not criticising Javascript for not being multi-threading, I’m criticising f(m) for trying to make it seem like it is.

I think it is this kind of attitude that has held back DHTML until recently – programmers look at the browser API and see that it is missing all of their beloved conventions like widget class hierarchies and threads, and so they sit down and write a giant Javascript library to fill that void.

Then they fall in love with their library and it grows into a giant 500k monstrosity that has to be downloaded with every app that they write. Don’t get me wrong, these libraries do a lot of great things, but those things could be done just as quickly without the added dependency if you just accept the limitations of JS and the DOM and work with them.

Comment by Joe — May 25, 2005

You are right Alex, there is no multithreading in Javascript.

The continuation trick is not about multithreading but about eliminating the need to *explicitely* define a lot of small callbacks.

It just builds the callbacks on the fly thru closures.

Though it may *appear* to work like multithreading because whenever a callback is “in waiting” other events will trigger execution of whatever event handler they are plugged to.

The difference with respect to full stroke multithreading is that no “microthread” (sort of…) will preempt a running event handler, control has to be reliquished, i.e. the event handler has to run to completion.

And, no Joe, the ‘continuate.js’ is not a “monstrosity” it is only 5656 bytes (actually less than 2000 excluding comments) and you are free to reuse it if you can live with its limitations.

Debugging the code which has been wrapped up in the closures is not always a piece of cake either…

But I still feel it is a valuable tradeoff.

Comment by Kevembuangga — May 25, 2005

Hi Joe,

I’m glad to find out that I misunderstood you =)

So I almost agree with everything you are saying, up until the point where you make the assumption that changing the perspective of programmers is (or should be) cost-free. I’m one of the guys working on those allegedly-500K toolkits (http://dojotoolkit.org), and I assert that:

1.) that many conventions of “normal” programming are useful
2.) these things don’t have to be 500K in deployment. Not by a long shot.

People didn’t invent widget class hierarchies because it’s fun. They did it because writing xlib and gdi function calls to draw everything really sucks. Grabbing StructureNotifyMask structs to get input isn’t very productive. And that’s the crux of the problem. You solution says “you must all pay a high initial mental price, then you should be able to build things that work well at high ongoing cost” while throwing tools at the situation changes that to be “you may pay a lower initial cost, but you might have to pay more in the future for better performance”. I argue that the market will always reward the second approach. The history of computers is proof enough of that.

Sooooo…what to do next? Well, you’ve outlined the first normal reaction: fill in the gaps w/ libraries. You’ve also identified the biggest hurdle to their use, but that sounds like a tools problem to me, and not necessarily a fundamental limitation. We’re working on some Open Source tools to make this a reality so that you only get what you need (meaning you only pay the latency price for what you *want* to pull down the wire). Basic utilities like a package system and AOP-style event handling make for a prett small deployment package . Send me mail (alex@dojotoolkit.org) if you want a more detailed description of how we’re trying to do this.

Regards

Comment by Alex Russell — May 25, 2005

I apologize for my rude flaming tone earlier. I’m just a little annoyed because I keep reading this blog hoping to find a). practical solutions to Ajax problems, and b). compelling real-world uses of Ajax, and instead I just keep reading about a bunch of pure Javascript abstractions to problems which, in my opinion, are not severe enough to justify adding even an extra 2k to my pages.

f(m)’s Threading module is not a “monstrosity” on its own, but if you’re an Ajax programmer and you plan to use existing libraries, and you have to use a combination like Dojo, wz_dragdrop, and f(m) to solve all of your problems, what you wind up with may very well be a monstrosity. Even Dojo just by itself is no lightweight. All of the classic DHTML libraries like Dan Steinman’s thing suffered from this problem as well.

The only framework I’ve seem that seems to understand this problem is Backbase, which (I think), uses a server to pre-parse your Javascript and cut out the code that you’re not using (in addition to obfuscating it). If it doesn’t do this, well, it should :) In spite of this, Backspace pages still feel a little heavy to me with the 5 second delay on page load.

The Holy Grail is a comprehensive Javascript library in which you do not pay a price for code that you don’t use, and pages load instantly without the “Loading…” delay while all the dependencies are sorted out and scripts are loaded.

Comment by Joe — May 25, 2005

So Dojo does include tools to strip out what you’re not using. Right now, however, they aren’t part of the normal build process because people aren’t really calmoring for it. Check out jslink.pl in our SVN repo:

http://dojotoolkit.org/svn/dojo/buildscripts/jslink.pl

Before you even get to this step, however, Dojo already gives you a lot of options for cutting down what you include. If you make a “profile build”, the dependency system will automatically sort out which packages to load based on coarse-grained dependencies. Only these packages will get included in a generated __package__.js file. I know this process isn’t well-documented right now, but ping the list or send me mail for more details. The build tools also (optionally) strip out whitespace and comments from this now-concatenated set of packages (which are, hopefully, only the things you need).

Profile builds are significantly faster than the normal “uncompressed” version of the tool but don’t require that developers entirely rework they way they use the code. Using a built “__package__.js” file is just a special case of using the “uncompressed” versions. This is what we mean by incrementally paying the price for optimization.

Also, we have just recently added drag-and-drop support, so you should be able to stop including wz_draganddrop. Also, I’d be curious to know what parts of f(m) you need to solve your app building issues.

Regards

Comment by Alex Russell — May 25, 2005

This threading library uses closures as far as I can tell; is it really safe to use closures for cross browser programming as long as IE has such memory leak issues when referencing DOM/COM objects from a closure? Most closures are for anonymous event handlers or for working with ActiveX scripted objects like XmlHttpRequest, so almost all of them are potentially susceptible to the IE closure memory leak issue (see http://jibbering.com/faq/faq_notes/closures.html#clMem for details).

Comment by Brad Neuberg — May 30, 2005

I love assumptions…

Hi Joe. I’m the guy that wrote the threading implementation in f(m). Well, I’m the guy that wrote f(m). So, in the spirit of explanations and to help disabuse you of your notions about f(m) (and by correlation, dojo)…

The Threading namespace in f(m) was aimed at creating a generic Timer class, as well as creating a basic singleton worker “threading” queue, similar to the one you’ll find in the .NET Framework. It was never intended to serve as the basis for asynchronous work within Javascript; it was intended to facilitate animations (which a lot of people were asking me for at the time) and to facilitate fire-and-forget functionality (i.e. background processes). Closures in their own right are a better mechanism for asynchronous work, and it’s a native part of the language.

As far as your comment about f(m) being one of these 500k+ frameworks, I will tell you that it was deliberately designed to *not* be that; in fact, the only thing you really need to use it is the Import function, and even then if you wanted to go through the files you want to use and remove the Import statements, you can do things the old fashioned way by including a bunch of script tags. I hate bloated frameworks as much as you do.

At the same time, I got very tired of having to take someone else’s code that steps all over the global object and window events and rewrite it to work with other things. I did my best to make what’s there in f(m) as isolated as possible (which I felt was more important than keeping it superlightweight).

Please bear in mind that f(m) was an experiment, and (in my mind) is still an incomplete library. But the point of it is that *it is a library* and not a framework.
….
Ok, that aside, to Brad: yes, there is a danger of memory leaks in IE, the key to avoiding it is to make sure you don’t assign any permanent reference to browser objects. In other words, instead of assigning a reference to an element as a property of an object, keep a reference to the ID of that element, and get the handle to the element when you need it and only when you need it.

Comment by Tom Trenka — May 31, 2005

Oh, almost forgot…Joe, just as an fyi, I wrote that code in April 2003, long before this hoopla over Ajax was around…

Comment by Tom Trenka — May 31, 2005

Just curious, but has anyone used SACK for “synchronous” requests?

For instance I have a variety of rules that need to be enforced based on the results of other requests.

My prior solution used a purely synchronous IE only solution and I am updating to use SACK and thus be more cross-browser compliant (the app has been in use since 2001 hence the initial IE only solution).

I can’t seem to get anything to work right if I use SACK in a synchronous fashion – so instead I am using setTimeout calls here and there. The problem there is if a response is slower than the timeout in coming back the results of the later calls will be invalid.

I would prefer a graceful failure to inaccurate results and hence am looking to use SACK synchronously. Any ideas?

Thanks

Comment by Bill — June 8, 2005

sorry for the totally off topic post. uggh, I thought I was in a different browser window :O)

Comment by Bill — June 8, 2005

read this
http://itadapter.blogspot.com/2006/11/java-script-multi-threading.html

Comment by ITAdapter — January 28, 2007

There are some thoughts about threading in JavaScript. I think it is real to simulate multi-threading by using continuation. By the way Windows is working with threads on single proc, so why script couldn’t work at many threads at single script enjine.

Comment by Frog007 — August 1, 2007

http://rightdev.blogspot.com/2007/07/multithreading-at-javascript.html

Comment by Frog007 — August 1, 2007

All the people saying that multithreading isn’t possible in javascript, because there are no threads are not really smart. The same way I could say: If there is only one processor, there is no multithreading and no multitasking possible, you just have one processor.

So, we must say: There is no “preemtive” multitasking/threading, because we can’t save/restore the current status of the javascript engine, that would be right, but do you remember DOS times? Did you write games in assembly language? No threading support available, protected mode beeing not possible due to invalid hardware drivers and no more BIOS function call (bevore VESA was there)?

So, what we could implement kind a easy is “coopertive” multitasking, sure this is little harder to develop tasks as in “preemptive” model, but well, that the price we’ve to pay. Example for a very slow loop in cooperative multitasking:

function my_thread() {
var thread = Thread.getCurrentThread();
var me = thread.Stack;
switch( thread.IP ) {
case 0:
me.i = 0;
if( thread.yield(1) ) return;
case 1:
for( ; me.i

Comment by Alexander Weber — October 19, 2007

case 1:
for( ; me.i

Comment by Alexander Weber — October 19, 2007

Please delete the other posts, you should implement quoting and not just truncate the post.

All the people saying that multithreading isn’t possible in javascript, because there are no threads are not really smart. The same way I could say: If there is only one processor, there is no multithreading and no multitasking possible, you just have one processor.

So, we must say: There is no “preemtive” multitasking/threading, because we can’t save/restore the current status of the javascript engine, that would be right, but do you remember DOS times? Did you write games in assembly language? No threading support available, protected mode beeing not possible due to invalid hardware drivers and no more BIOS function call (bevore VESA was there)?

So, what we could implement kind a easy is “coopertive” multitasking, sure this is little harder to develop tasks as in “preemptive” model, but well, that the price we’ve to pay. Example for a very slow loop in cooperative multitasking:

function my_thread() {
var thread = Thread.getCurrentThread();
var me = thread.Stack;
switch( thread.IP ) {
case 0:
me.i = 0;
if( thread.yield(1) ) return;
case 1:
for( ; me.i

Comment by Alexander Weber — October 19, 2007

You know what – I totally agree about javascript not supporting threads. I think the biggest argument to these ideas is that settineout isn’t creating instances of threads but is merely acting as a controller. For any serious application that requires a ton of highly optimzed client side code EX// a web based IDE – this method simply isn’t practical.

I built a raw implementation of this back in2003 as well and I can tell you que management is a total nightmare. Using settineout is a huge performance hit on apps that require thousands of iterations per second. One ends up writing iterators that yield to time over enumeration.

I agree that this technique may be great for ui animations and doc repaints – but it’s not a decent technique to combat the real limitations of javascript.

Comment by Badapple — January 16, 2009

Leave a comment

You must be logged in to post a comment.