Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Threading in JavaScript

1 view
Skip to first unread message

Gordan

unread,
Feb 1, 2003, 8:32:57 AM2/1/03
to
Hi!

I am aguessing that I am probably expecting WAY too much from JavaScript
implementations here, but I'll ask anyway... ;-)

Is there any way to achieve _actual_ threading in JS? I know that in theory,

setTimeout("myFunction(myParams)", Timeout);

SHOULD fork a new thread to execute myFunction(myParams), but I have found
that it doesn't happen quite like that. On both IE6 and Mozilla 1.2.1 the
execution is SCHEDULED for NO LESS than Timeout miliseconds in the future.
This, however, doesn't GUARANTEE when the execution will begin.

What happens instead is that all setTimeout() started functions are
scheduled in the future and execute sequentially, one after another. They
do not interleave their execution.

I know that implementing safe threading is difficult, and that it opens a
whole new can of worms as far as variable locking/sharing is concerned, but
is such a feature present in ANY DOM compliant browser today? Is it even
planned in ANY of the browsers? I would really like to avoid the path of
Java applets and ActiveX controls if at all possible.

TIA.

Gordan

Laurent Bugnion, GalaSoft

unread,
Feb 1, 2003, 8:44:04 AM2/1/03
to
Hi,

Multithreading (with all features allowing for safe threading, resource
locking, etc...) is available in many browsers: It's called Java applets
;-) In fact, it's one of the cases where I would recommend using an
applet over a scripting solution.

JavaScript doesn't offer multithreading inherently. But since you can
control an applet using JavaScript (in LiveConnect enabled browsers),
you can do what you want.

For LiveConnect matters:
http://www.galasoft-LB.ch/myjavascript/consulting/LiveConnect102

Laurent
--
Laurent Bugnion, GalaSoft
Webdesign, Java, JavaScript: http://www.galasoft-LB.ch
Private/Malaysia: http://mypage.bluewin.ch/lbugnion
Support children in Calcutta: http://www.calcutta-espoir.ch

Gordan

unread,
Feb 1, 2003, 8:56:19 AM2/1/03
to
Laurent Bugnion, GalaSoft wrote:

> Multithreading (with all features allowing for safe threading, resource
> locking, etc...) is available in many browsers: It's called Java applets
> ;-) In fact, it's one of the cases where I would recommend using an
> applet over a scripting solution.
>
> JavaScript doesn't offer multithreading inherently. But since you can
> control an applet using JavaScript (in LiveConnect enabled browsers),
> you can do what you want.
>
> For LiveConnect matters:
> http://www.galasoft-LB.ch/myjavascript/consulting/LiveConnect102

Thanks for the quick reply!

Using Java/LiveConnect is precisely what I was trying to avoid... :-(

I take it that both SpiderMonkey and Rhino only provide a single-threading
environment? And there is no browser that actually supports multi-threaded
JS?

Gordan

Douglas Crockford

unread,
Feb 1, 2003, 9:38:08 AM2/1/03
to
> Using Java/LiveConnect is precisely what I was trying to avoid... :-(

That is most wise.

> I take it that both SpiderMonkey and Rhino only provide a single-threading
> environment? And there is no browser that actually supports multi-threaded
> JS?

Nope. For applications based on short bursts of event-driven activity,
threading is less efficient and prone to deadlocks. What are you doing that
requires preemption?

http://www.crockford.com/javascript/javascript.html


Gordan

unread,
Feb 1, 2003, 12:40:17 PM2/1/03
to
Douglas Crockford wrote:

>> I take it that both SpiderMonkey and Rhino only provide a
>> single-threading environment? And there is no browser that actually
>> supports multi-threaded JS?
>
> Nope. For applications based on short bursts of event-driven activity,
> threading is less efficient and prone to deadlocks. What are you doing
> that requires preemption?

I would like to download multiple files simultaneously, process them
independently, and then independently update separate objects in a page
(e.g. DIVs containing some HTML data stripped out from the downloaded
files).

The reason why I want to handle them all independently is that the
application I am writing should scale to, potentially, hundreds of files
from which the relevant data is extracted. Unfortunately, the potential
latency on some sites can really hammer the performance, and one slow
download slows down the entire process, rather than just making one
specific DIV block take longer to generate.

It is also not useful to have to wait for the whole page to be generated
before being able to do anything with it. It would be much more useful if
each finished part of the page could be used independently, while the
remaining sections are being processed (e.g. scrolling, clicking, opening
links in a new window/frame, etc.).

I was thinking about working around this by using IFRAMEs instead of DIVs,
but I have found that the single-thread paradigm also spans frames within a
single browser instance.

The only workaround I can think of is creating a Java applet or a
plugin/ActiveX control combo (I need the app to be cross-browser) that can
take a URL, or a list of URLs and start downloading them independently.
Then I could fudge the delay loop using a recursive setTimeout() based
function for polling the status, and working around the problem that way.
It wouldn't work around the parallel page generation issues, but it would
at least work around the issue of not being able to fork multiple
simultaneous downloads.

The problem with this partial work-around is that I would have to write the
applets as well as the page generation code, but it is looking more and
more like I don't really have a choice.

Can anyone suggest a better way of doing this in a browser (short of writing
the whole thing as an applet)?

Thanks.

Gordan

Douglas Crockford

unread,
Feb 1, 2003, 1:56:49 PM2/1/03
to
> >> I take it that both SpiderMonkey and Rhino only provide a
> >> single-threading environment? And there is no browser that actually
> >> supports multi-threaded JS?
> >
> > Nope. For applications based on short bursts of event-driven activity,
> > threading is less efficient and prone to deadlocks. What are you doing
> > that requires preemption?
>
> I would like to download multiple files simultaneously, process them
> independently, and then independently update separate objects in a page
> (e.g. DIVs containing some HTML data stripped out from the downloaded
> files).

That doesn't require preemption. Make a separate <iframe> for each document.
The scripts in the incoming documents will run when they are ready. They can
cause the data to be delivered to the main page. No evil threads are
required.

> The reason why I want to handle them all independently is that the
> application I am writing should scale to, potentially, hundreds of files
> from which the relevant data is extracted. Unfortunately, the potential
> latency on some sites can really hammer the performance, and one slow
> download slows down the entire process, rather than just making one
> specific DIV block take longer to generate.

Asking a browser to manage hundreds of connections is [asking for a kick in
the] nuts. That kind of stuff is best managed by a server. Servers can be
good aggregators. Browsers will only break your heart. Check out
www.statesoftware.com for a good server.

> It is also not useful to have to wait for the whole page to be generated
> before being able to do anything with it. It would be much more useful if
> each finished part of the page could be used independently, while the
> remaining sections are being processed (e.g. scrolling, clicking, opening
> links in a new window/frame, etc.).
>
> I was thinking about working around this by using IFRAMEs instead of DIVs,
> but I have found that the single-thread paradigm also spans frames within
a
> single browser instance.
>
> The only workaround I can think of is creating a Java applet or a
> plugin/ActiveX control combo (I need the app to be cross-browser) that can
> take a URL, or a list of URLs and start downloading them independently.
> Then I could fudge the delay loop using a recursive setTimeout() based
> function for polling the status, and working around the problem that way.
> It wouldn't work around the parallel page generation issues, but it would
> at least work around the issue of not being able to fork multiple
> simultaneous downloads.
>
> The problem with this partial work-around is that I would have to write
the
> applets as well as the page generation code, but it is looking more and
> more like I don't really have a choice.
>
> Can anyone suggest a better way of doing this in a browser (short of
writing
> the whole thing as an applet)?

You have more [and better] choices than you know. The road you are currently
on is a hard and profitless on. I can consult on this if you need a guide.

http://www.crockford.com/


Gordan

unread,
Feb 1, 2003, 8:01:44 PM2/1/03
to
Douglas Crockford wrote:

>> >> I take it that both SpiderMonkey and Rhino only provide a
>> >> single-threading environment? And there is no browser that actually
>> >> supports multi-threaded JS?
>> >
>> > Nope. For applications based on short bursts of event-driven activity,
>> > threading is less efficient and prone to deadlocks. What are you doing
>> > that requires preemption?
>>
>> I would like to download multiple files simultaneously, process them
>> independently, and then independently update separate objects in a page
>> (e.g. DIVs containing some HTML data stripped out from the downloaded
>> files).
>
> That doesn't require preemption. Make a separate <iframe> for each
> document. The scripts in the incoming documents will run when they are
> ready. They can cause the data to be delivered to the main page. No evil
> threads are required.

Yes, I thought about that, but it makes the code more broken up and
synchronisation of what happens becomes more difficult. In a way, it moves
the difficulty from that of implementing safe pre-emptive threading to the
"userspace" code. But I guess it is a work-around.

Is it possible to use JavaScript to load an <iframe> and make a separate
function trigger once the iframe has been loaded? Something like

<IFRAME src="http://someurl" onLoad="MyFunction">

Will that work?

>> The reason why I want to handle them all independently is that the
>> application I am writing should scale to, potentially, hundreds of files
>> from which the relevant data is extracted. Unfortunately, the potential
>> latency on some sites can really hammer the performance, and one slow
>> download slows down the entire process, rather than just making one
>> specific DIV block take longer to generate.
>
> Asking a browser to manage hundreds of connections is [asking for a kick
> in the] nuts. That kind of stuff is best managed by a server. Servers can
> be good aggregators. Browsers will only break your heart. Check out
> www.statesoftware.com for a good server.

I have already implemented a prototype of this in a server based (CGI)
application. I am now hoping to move as much of the work as possible to the
client in order to save the resources. It can be very hard on both the
server and it's bandwidth proxying everything. If the data can travel from
the source directly to the client, it makes the whole system much more
distributed and scaleable.

Regards.

Gordan

Douglas Crockford

unread,
Feb 1, 2003, 8:09:39 PM2/1/03
to
> >> >> I take it that both SpiderMonkey and Rhino only provide a
> >> >> single-threading environment? And there is no browser that actually
> >> >> supports multi-threaded JS?
> >> >
> >> > Nope. For applications based on short bursts of event-driven
activity,
> >> > threading is less efficient and prone to deadlocks. What are you
doing
> >> > that requires preemption?
> >>
> >> I would like to download multiple files simultaneously, process them
> >> independently, and then independently update separate objects in a page
> >> (e.g. DIVs containing some HTML data stripped out from the downloaded
> >> files).
> >
> > That doesn't require preemption. Make a separate <iframe> for each
> > document. The scripts in the incoming documents will run when they are
> > ready. They can cause the data to be delivered to the main page. No evil
> > threads are required.
>
> Yes, I thought about that, but it makes the code more broken up and
> synchronisation of what happens becomes more difficult. In a way, it moves
> the difficulty from that of implementing safe pre-emptive threading to the
> "userspace" code. But I guess it is a work-around.
>
> Is it possible to use JavaScript to load an <iframe> and make a separate
> function trigger once the iframe has been loaded? Something like
>
> <IFRAME src="http://someurl" onLoad="MyFunction">
>
> Will that work?

No. <iframe> doesn't do onload. I think you have some deep misconceptions
about single-thread architecture. It makes things easier, not harder, unless
you are trying to simulate multi-thread architecture in it. Work with the
grain.

> >> The reason why I want to handle them all independently is that the
> >> application I am writing should scale to, potentially, hundreds of
files
> >> from which the relevant data is extracted. Unfortunately, the potential
> >> latency on some sites can really hammer the performance, and one slow
> >> download slows down the entire process, rather than just making one
> >> specific DIV block take longer to generate.
> >
> > Asking a browser to manage hundreds of connections is [asking for a kick
> > in the] nuts. That kind of stuff is best managed by a server. Servers
can
> > be good aggregators. Browsers will only break your heart. Check out
> > www.statesoftware.com for a good server.
>
> I have already implemented a prototype of this in a server based (CGI)
> application. I am now hoping to move as much of the work as possible to
the
> client in order to save the resources. It can be very hard on both the
> server and it's bandwidth proxying everything. If the data can travel from
> the source directly to the client, it makes the whole system much more
> distributed and scaleable.

You have some profound structural inefficiencies, it sounds like. Moving
them to the client is not a solution. I contend there is a better way to
think about the problem.

http://www.crockford.com/


Steve van Dongen

unread,
Feb 1, 2003, 10:53:34 PM2/1/03
to
On Sat, 01 Feb 2003 17:40:17 +0000, Gordan <gordan@_NOSPAM_bobich.net>
wrote:

Sounds like you should look into XMLHTTP
http://jibbering.com/2002/4/httprequest.html

Regards,
Steve

Fox

unread,
Feb 2, 2003, 12:00:18 AM2/2/03
to
while you are right that there is no guarantee that execution of functions will happen as
precisely timed, you have no guarantee of that in Java either -- although you have a better
"expectation" of precision if you set the priority to high [around 10, depending on what the
sandbox will allow, you still only get to *request* priority!].

Most people don't get threads in JavaScript. You have two options: setTimeout (a one time
execution) or setInterval (for repetitive executions).

The thing you have to remember with JS is that it's not that fast -- so don't overburden the threads.

How to run multiple "asynchronous" threads?

maintain multiple variables, or an array of timer. To make demonstration easy, I'll use multiple variables...


var timer_for_f_one = null;
var timer_for_f_two = null;
var timer_for_f_three = null;

function
startAnimations()
{

timer_for_f_one = setTimeout("f_one()", 500);
timer_for_f_two = setTimeout("f_two()", 750);
timer_for_f_three = setTimeout("f_three()","333");
}

function
f_one()
{
// do stuff every 1/2 second
timer_for_f_one = setTimeout("f_one()", 500); // repeat
}

function
f_two()
{
// do stuff every 3/4 second
timer_for_f_two = setTimeout("f_one()", 750); // repeat
}

function
f_three()
{
// do stuff every 1/3 second
timer_for_f_three = setTimeout("f_one()", 333); // repeat
}

If you use setTimeout without saving it's reference, then the browser will use a "blind
reference" to save the timeout ref. The problems with this, you have already discovered.

Also, be good to your users -- when you're finished with a timer -- clear it!

onunload = function()
{
if(timer_for_f_one) clearTimeout(timer_for_f_one);
if(timer_for_f_two) clearTimeout(timer_for_f_ two);
if(timer_for_f_three) clearTimeout(timer_for_f_three);

// same is (especially) true for setInterval
}

NOT clearing timers causes problems for some browsers *on subsequent pages*, and whereas your
page might work perfectly, the browser is headed for a crash a few pages down the line.


Here is a cut n paste demo (uses setInterval and for new DOM browsers [getElementById])::


<xmp><!-- remove this line to run -->

<style>

#one {
position: absolute;
top: 0;
left: 0;
width: 100;
height: 100;
background-color: red;
color: white;
font: 60px Verdana;
font-weight: bold;
text-align: center;
line-height: 95px;
}

#two {
position: absolute;
top: 0;
left: 0;
width: 100;
height: 100;
background-color: green;
color: white;
font: 60px Verdana;
font-weight: bold;
text-align: center;
line-height: 95px;

}

#three {

position: absolute;
top: 0;
left: 0;
width: 100;
height: 100;
background-color: blue;
color: white;
font: 60px Verdana;
font-weight: bold;
text-align: center;
line-height: 95px;
}

</style>

<script language = javascript>

var timer = [null, null, null];

var winWidth = 0;
var winHeight = 0;


onload = function()
{

winWidth = document.all ? document.body.clientWidth : window.innerWidth;
winHeight = document.all ? document.body.clientHeight : window.innerHeight;

// this is "slow" to make it obvious that executions
// are separate and that these are individual threads

timer[0] = setInterval("recalcPos('one')", 1000);
timer[1] = setInterval("recalcPos('two')", 2000);
timer[2] = setInterval("recalcPos('three')", 3000);
}


function
recalcPos(which)
{
var left = Math.floor(Math.random() * (winWidth - 100));
var top = Math.floor(Math.random() * (winHeight - 100));

var lyr = document.getElementById(which).style;

lyr.left = left;
lyr.top = top;

// alert(which + "\n" + top + "\n" + left);
}

onunload = function()
{
for(var i = 0;i < timer.length; i++)
if(timer[i]) clearInterval(timer[i]);
}

</script>

<body>

<div id = one>1</div>
<div id = two>2</div>
<div id = three>3</div>

</body>

</xmp><!-- remove this line to run -->

Fox
*************

Gordan

unread,
Feb 2, 2003, 8:40:11 AM2/2/03
to
Douglas Crockford wrote:

>> Is it possible to use JavaScript to load an <iframe> and make a separate
>> function trigger once the iframe has been loaded? Something like
>>
>> <IFRAME src="http://someurl" onLoad="MyFunction">
>>
>> Will that work?
>
> No. <iframe> doesn't do onload. I think you have some deep misconceptions
> about single-thread architecture. It makes things easier, not harder,
> unless you are trying to simulate multi-thread architecture in it. Work
> with the grain.

So, in order to defeat the waiting-for-download problem, each data file
should be processed as it comes in. If I use the iframe to load each file
separately, how can I make it execute the processing function as soon as it
has finished loading? That way I don't need threading in JS, because I can
download each file separately, and process each file as soon as it has
downloaded - provides I can trigger a function when an iframe finishes
loading...

>> I have already implemented a prototype of this in a server based (CGI)
>> application. I am now hoping to move as much of the work as possible to
>> the
>> client in order to save the resources. It can be very hard on both the
>> server and it's bandwidth proxying everything. If the data can travel
>> from the source directly to the client, it makes the whole system much
>> more distributed and scaleable.
>
> You have some profound structural inefficiencies, it sounds like. Moving
> them to the client is not a solution. I contend there is a better way to
> think about the problem.

How exactly? If a number of files need to be downloaded and processed, then
if that processing is done on the server, the server has to download them
all (expensive on bandwidth), process them all (expensive on CPU), and send
them to the client (more expense on bandwidth).

If the server only handles things like control and authentication messages,
and the data travels straight to the client, it gets processed on the
client. The overhead of sending processed data to the client is completely
avoided, and due to latencies involved, it will probably all finish faster.

I agree with you that there is an EASIER way to think about the problem, but
I have already implemented that easy solution. Now I'm trying to improve
upon it.

Regards.

Gordan

Gordan

unread,
Feb 2, 2003, 8:43:03 AM2/2/03
to
Steve van Dongen wrote:

> On Sat, 01 Feb 2003 17:40:17 +0000, Gordan <gordan@_NOSPAM_bobich.net>
> wrote:

[snip]

>>I was thinking about working around this by using IFRAMEs instead of DIVs,
>>but I have found that the single-thread paradigm also spans frames within
>>a single browser instance.
>>
>>The only workaround I can think of is creating a Java applet or a
>>plugin/ActiveX control combo (I need the app to be cross-browser) that can
>>take a URL, or a list of URLs and start downloading them independently.
>>Then I could fudge the delay loop using a recursive setTimeout() based
>>function for polling the status, and working around the problem that way.
>>It wouldn't work around the parallel page generation issues, but it would
>>at least work around the issue of not being able to fork multiple
>>simultaneous downloads.

[snip]

> Sounds like you should look into XMLHTTP
> http://jibbering.com/2002/4/httprequest.html

Thank for the reply, Steve.

I am already aware of the XMLHTTP method for downloading things.
Unfortunately, it only allows the download of one file at a time, which is
why I was looking for a different solution that allows me to download
multiple files simultaneously.

Regards.

Gordan

Gordan

unread,
Feb 2, 2003, 9:39:49 AM2/2/03
to
Fox wrote:

> while you are right that there is no guarantee that execution of functions
> will happen as precisely timed, you have no guarantee of that in Java
> either -- although you have a better "expectation" of precision if you set
> the priority to high [around 10, depending on what the sandbox will allow,
> you still only get to *request* priority!].

Yes, but you also HAVE a guarantee that the functions will execute
sequentially, NOT in parallel. Or am in error there?

> Most people don't get threads in JavaScript. You have two options:
> setTimeout (a one time execution) or setInterval (for repetitive
> executions).

Yeah, I figured that this was the only construct in JS that would even
theoretically allow for threading (no fork() <gasp!> ;-) ).

> The thing you have to remember with JS is that it's not that fast -- so
> don't overburden the threads.

It's not all that slow if done properly, either. Manipulating the page and
parsing DOM can be slow, but I have found it to be on the par with other
inpterpreted languages.

> How to run multiple "asynchronous" threads?
>
> maintain multiple variables, or an array of timer. To make demonstration
> easy, I'll use multiple variables...
>
>
> var timer_for_f_one = null;
> var timer_for_f_two = null;
> var timer_for_f_three = null;

[snip]

> timer_for_f_one = setTimeout("f_one()", 500);
> timer_for_f_two = setTimeout("f_two()", 750);
> timer_for_f_three = setTimeout("f_three()","333");

> function
> f_one()
> {
> // do stuff every 1/2 second
> timer_for_f_one = setTimeout("f_one()", 500); // repeat
> }
>
> function
> f_two()
> {
> // do stuff every 3/4 second
> timer_for_f_two = setTimeout("f_one()", 750); // repeat
> }
>
> function
> f_three()
> {
> // do stuff every 1/3 second
> timer_for_f_three = setTimeout("f_one()", 333); // repeat
> }

So, each function recursively schedules itself for the next run. OK, I
understand that.

> If you use setTimeout without saving it's reference, then the browser will
> use a "blind
> reference" to save the timeout ref. The problems with this, you have
> already discovered.

I have just tried the above solution as you described it. I am still unable
to get parallel execution to work. I have a test page that has two text
boxes textbox1 and textbox2. There are two functions running through loops
that assign the value of the iterator to textbox1.value and textbox2.value.

Even with saving the return of setTimeout to a variable (I used a global
scope array), they STILL execute one AFTER the other. The two loops do not
interleave, and the second text box still doesn't update until the first
one is completely finished.

I have tried this on both Mozilla and IE, and both behave the same way. Have
I missed something?

Here is my page code:

<SCRIPT language =" JavaScript">
<!--
// Global Variables
var ThreadHandle = new Array();
var DelayLoop = new Array();

function ThreadTest()
{
ThreadHandle[0] = setTimeout("Thread1()", 20);
ThreadHandle[1] = setTimeout("Thread2()", 10);
}

function Thread1()
{
var ThreadText1 = document.getElementById("ThreadText1");
var i;

for (i = 0; i < 100; i++)
{
ThreadText1.value = i;

// I'm told adding setTimeout() in loops helps
// with giving the browser a bit of time to
// catch up...
if (DelayLoop[0])
{
clearTimeout(DelayLoop[0]);
}

DelayLoop[0] = setTimeout("", 0);
}
}

function Thread2()
{
var ThreadText2 = document.getElementById("ThreadText2");
var i;

for (i = 0; i < 1000; i+=10)
{
ThreadText2.value = i;

if (DelayLoop[1])
{
clearTimeout(DelayLoop[1]);
}

DelayLoop[1] = setTimeout("", 0);
}
}

function Body_onUnload()
{
var i;

for (i in ThreadHandle)
{
if (ThreadHandle[i])
{
clearTimeout(ThreadHandle[i]);
}
}
}
//-->
</SCRIPT>

> Also, be good to your users -- when you're finished with a timer -- clear
> it!
>
> onunload = function()
> {
> if(timer_for_f_one) clearTimeout(timer_for_f_one);
> if(timer_for_f_two) clearTimeout(timer_for_f_ two);
> if(timer_for_f_three) clearTimeout(timer_for_f_three);
>
> // same is (especially) true for setInterval
> }
>
> NOT clearing timers causes problems for some browsers *on subsequent
> pages*, and whereas your page might work perfectly, the browser is headed
> for a crash a few pages down the line.

Thanks, I'll keep that in mind.

Regards.

Gordan

Stephen

unread,
Feb 2, 2003, 11:56:35 AM2/2/03
to

Will these (possibly as many as 100) files come from the same server or
from multiple different servers? Do you have control over all/any of
these servers' configs?

How do you envision "download[ing] multiple files simultaneously"
happening across TCP/IP using HTTP? What networking issues have you
considered in this context?

Regards,
Stephen

Steve van Dongen

unread,
Feb 2, 2003, 5:04:23 PM2/2/03
to

If you use asyncronous mode you can download as many files as you
want. True, on a strictly technical level, the callbacks will be
processed syncronously because javascript is single threaded, but
there's nothing you can do about that and you'll have that problem
with any solution that involves javascript.
http://msdn.microsoft.com/library/en-us/xmlsdk/htm/xml_mth_or_4to4.asp

The other thing to consider is that the HTTP 1.0 and 1.1
specifications allows for four and two socket connections respectively
per server, per process. You can spawn 100 threads and make 100
requests if you want; however, all but 4/2 will be blocked unless they
are made in different processes. There is a registry key that you can
set to increase the client-side limit but, if I remember right,
neither cannot be set higher than 16.
http://support.microsoft.com/default.aspx?scid=kb;en-us;183110

I use XMLHTTP along with setTimeout and setInterval in my pages -- I
make 10-15 requests every 5 seconds or so -- and it works really
nicely. I'm on an intranet with a responsive server though so the
HTTP limit doesn't really affect me. If you're developing for an
internet site you might have some trouble because of the higher
latency.

Regards,
Steve

Steve van Dongen

unread,
Feb 2, 2003, 5:57:08 PM2/2/03
to
On Sun, 02 Feb 2003 14:39:49 +0000, Gordan <gordan@_NOSPAM_bobich.net>
wrote:

Yeah, kind of...

> for (i = 0; i < 100; i++)
> {
> ThreadText1.value = i;
>
> // I'm told adding setTimeout() in loops helps
> // with giving the browser a bit of time to
> // catch up...

That's not quite right. Using setTimeout *INSTEAD* *OF* or in
conjunction with a loop will give the browser a bit of time to catch
up. setTimeout only schedules some script to run at some point in the
future; you only give the browser time to do something else if you
don't do something else yourself.

> if (DelayLoop[0])
> {
> clearTimeout(DelayLoop[0]);
> }
>
> DelayLoop[0] = setTimeout("", 0);
> }
> }

I your code, your setTimeout is really not doing anything. Your first
for loop runs, burning up all the available processor time, and
afterwards your other for loop runs.

The idea is to have your Thread1 and Thread2 functions do only a
little bit of real work, then use setTimeout to run them again a
little later. I changed Thread1 to do 1 iteration of the "loop" per
function call and Thread2 to do 10 iterations per function call.

// Global Variables
var ThreadHandle = new Array();

function ThreadTest()
{
ThreadHandle[0] = setTimeout("Thread1(0)", 20);
ThreadHandle[1] = setTimeout("Thread2(0)", 10);
}

function Thread1(i)


{
var ThreadText1 = document.getElementById("ThreadText1");

if (i < 1000)
{
ThreadText1.value = i;
ThreadHandle[0] = setTimeout("Thread1(" + (i+1) + ")", 20);
}
}

function Thread2(i)


{
var ThreadText2 = document.getElementById("ThreadText2");

if (i < 10000)
{
for (var j=0; i<10000 && j<10; i++, j++)
ThreadText2.value = i;
ThreadHandle[1] = setTimeout("Thread2(" + (i+1) + ")", 10);
}
}

function Body_onUnload()
{
for (var i=0; i<ThreadHandle.length; i++)


{
if (ThreadHandle[i])
clearTimeout(ThreadHandle[i]);
}
}

Regards,
Steve

Robert Bates

unread,
Feb 2, 2003, 6:18:52 PM2/2/03
to
In reference to the HTTP/1.0 and HTTP/1.1 limits - in my experience
regardless of what you jack the client side to, you're still being held back
by the server. With most servers today being HTTP/1.1 compliant, you only
get two sockets per process (and in some cases per IP address box - depends
again on the server). Believe me, I've tried everything in some current
client's code to work around that limit as they use SOAP for their data
retrieval layer on some screens with 10-12 queries, and the server holds me
up every time...

Best of luck!
-Rob

"Steve van Dongen" <ste...@hotmail.com> wrote in message
news:8m1r3v0305sum1vrc...@4ax.com...

Gordan

unread,
Feb 2, 2003, 6:26:03 PM2/2/03
to
Stephen wrote:

>> Thank for the reply, Steve.
>>
>> I am already aware of the XMLHTTP method for downloading things.
>> Unfortunately, it only allows the download of one file at a time, which
>> is why I was looking for a different solution that allows me to download
>> multiple files simultaneously.
>>
>
> Will these (possibly as many as 100) files come from the same server or
> from multiple different servers? Do you have control over all/any of
> these servers' configs?

No, no control over any server should be assumed. In theory, it could be any
internet URL.

> How do you envision "download[ing] multiple files simultaneously"
> happening across TCP/IP using HTTP? What networking issues have you
> considered in this context?

I'm not sure what you mean by this. What I would like to do is fork a
separate connection to each server and go a GET request. Then either wait
for all of them to finish (not very efficient), or start processing for
output as each separate download finishes (more desireable, but again, this
gets academic without proper threading).

While there isn't a "hard" limit on the number of pages that may be
downloaded at the same time, I do not want to build in a specific limit.
Ultimately, it will be limited by the bandwidth and other resources of the
usre's machine. 100 files is a very extreme case. In reality, it is not
likely to exceed 10, probably closer to 5 in the average case. Of course,
if I could limit the number of simultaneous downloads, that is a useful and
desirable feature, but that starts getting academic, unless there is a way
to do parallel page retrievals in the first place.

I know that this sounds like it could be dealt with through a "funnel"
server, but I'm trying to come up with a solution that I will be able to
re-cycle in other things that MIGHT need the extra scaleability in the
future...

Regards.

Gordan

Gordan

unread,
Feb 2, 2003, 6:33:02 PM2/2/03
to
Steve van Dongen wrote:

Ah, so that's where I've been missing. I wasn't aware of the asynchronous
mode. Thanks. That is most useful. I don't suppose you know if there is a
way to do something similar in Mozilla?

> The other thing to consider is that the HTTP 1.0 and 1.1
> specifications allows for four and two socket connections respectively
> per server, per process. You can spawn 100 threads and make 100
> requests if you want; however, all but 4/2 will be blocked unless they
> are made in different processes. There is a registry key that you can
> set to increase the client-side limit but, if I remember right,
> neither cannot be set higher than 16.
> http://support.microsoft.com/default.aspx?scid=kb;en-us;183110

That's OK, even 2 is still much better than 1.

> I use XMLHTTP along with setTimeout and setInterval in my pages -- I
> make 10-15 requests every 5 seconds or so -- and it works really
> nicely. I'm on an intranet with a responsive server though so the
> HTTP limit doesn't really affect me. If you're developing for an
> internet site you might have some trouble because of the higher
> latency.

If it will go as far as 16 on IE/Windows, that should be more enough. All I
have to do now is find out if Mozilla supports a similar trick.

Thanks for the information. I appreciate it.

Gordan

Gordan

unread,
Feb 2, 2003, 6:37:22 PM2/2/03
to
Steve van Dongen wrote:

[snip]

> I your code, your setTimeout is really not doing anything. Your first
> for loop runs, burning up all the available processor time, and
> afterwards your other for loop runs.
>
> The idea is to have your Thread1 and Thread2 functions do only a
> little bit of real work, then use setTimeout to run them again a
> little later. I changed Thread1 to do 1 iteration of the "loop" per
> function call and Thread2 to do 10 iterations per function call.

[snip]

Right, I get it. So I cannot really have separate threads running
simultaneously. I just get each "thread" to schedule itself in the future,
iteration by iteration. OK, I can see how that works. Not quite proper
"threading", though. :-(

Thanks, anyway. It's a useful method for "pretending" that there are several
things running at the same time. ;-)

Regards.

Gordan

Steve van Dongen

unread,
Feb 2, 2003, 8:18:41 PM2/2/03
to
On Sun, 02 Feb 2003 23:33:02 +0000, Gordan <gordan@_NOSPAM_bobich.net>
wrote:

Yes, Mozilla implements it as well. Refer to the link in my original
response.
http://jibbering.com/2002/4/httprequest.html

Regards,
Steve

Stephen

unread,
Feb 2, 2003, 10:14:16 PM2/2/03
to
Gordan wrote:
> Stephen wrote:
>
>
snip some...

>>>I am already aware of the XMLHTTP method for downloading things.
>>>Unfortunately, it only allows the download of one file at a time, which
>>>is why I was looking for a different solution that allows me to download
>>>multiple files simultaneously.
>>>
>>
>>Will these (possibly as many as 100) files come from the same server or
>>from multiple different servers? Do you have control over all/any of
>>these servers' configs?
>
>
> No, no control over any server should be assumed. In theory, it could be any
> internet URL.
>
>
>>How do you envision "download[ing] multiple files simultaneously"
>>happening across TCP/IP using HTTP? What networking issues have you
>>considered in this context?
>
>
> I'm not sure what you mean by this.

Well, this may depend on whether your concept is to obtain these data
files from a single server or from a multitude of different servers. But ...

I am thinking that once the requests go out the wire you're at the mercy
of the network. It could be that all the fancy multi-threading in the
world (assuming this were possible) would come to naught because of
network considerations:

--overhead for multiple tcp connections rather than one persistent
connection
--timeout limits placed by server configs on the time allowed for any
single persistent connection
--limitations server configs might place on the number of simultaneous
connections allowed from a single client (thus my question above about
whether you control the servers and thus the servers' configs)
--network congestion that could increase latency because of a large
number of requests/responses --especially responses coming back to the
single point of origin
--user's bandwidth

it could be these and related issues would completely negate any
advantage you obtain (or believe you might obtain) by doing
"simultaneous downloads"

So ... do you have a vision of what happens on the network and on the
server if, say, 100 requests from the same client hit the server roughly
simultaneously? Simply meaning, if the network considerations of a large
number of "simultaneous" downloads might overwhelm any advantage, then
the cost outweighs benefit, and we've probably used up more discussion
time than the issue is worth. But that's an empirical determination yet
to be made...

What I would like to do is fork a
> separate connection to each server and go a GET request.

Is this really necessary? I understand the browser to work something
like the following:

A stream of text arrives at the browser. This stream of text is an HTML
page. The browser parses this incoming stream. During this parse it may
encounter URLs that cause it to issue additional requests for those
resources. Some of these might be <img src=> or <script src=> or <link
rel=stylesheet href=> or <iframe src=> or basically anything that has a
URL that the browser must obtain in order to render or otherwise process
the page.

The browser will issue these additional requests as it encounters the
URLs while parsing the input stream; it then continues parsing the
input. If it encounters another URL it needs, the browser makes this
next request, and so forth.

This is a broad-stroke scenario, but I believe it is substantially
accurate. If so, where is the need for multi-threading?

(I'm dealing only with the downloading issue here...)

Then either wait
> for all of them to finish (not very efficient), or start processing for
> output as each separate download finishes (more desireable, but again, this
> gets academic without proper threading).
>

I believe it's been previously mentioned that if the data come from
different servers from the main page, there could be security issues re
"processing" this data.

> While there isn't a "hard" limit on the number of pages that may be
> downloaded at the same time, I do not want to build in a specific limit.
> Ultimately, it will be limited by the bandwidth and other resources of the
> usre's machine. 100 files is a very extreme case. In reality, it is not
> likely to exceed 10, probably closer to 5 in the average case.

It certainly seems that if the typical number of files is 5 or 10, and
this happens, say 99+% of the time(?), then the amount of effort you're
putting into this simultaneous-downloads/multi-threading issue is really
excessive. Just do things the normal way. (Unless, are these data files
Really Huge?) In the one case out of (100?)(1000?)(10,000?) where you
need 100 files -- well, is it worth all this effort for that small a
number of cases?


New consideration:
The following may not be very fruitful, but might be worth some
research... (not a javascript solution, though; applies to downloading
only)... (And, this deals with obtaining files from the same server.)

There is a feature of HTTP 1.1 that is not, AFAIK, supported at all in
browsers or HTTPRequest-type approaches, but which you might be able to
implement in an applet or activex object. This feature is "pipelining"
in which several requests can be -- well, pipelined -- within the same
HTTP request.

The normal way is a single "request line" followed by (in http 1.1) 1 or
more headers. In pipelining, one can place several request lines, in
sequence, before the headers. See RFC 2616, section 8.1.1
(Connections/Persistent Connections/Purpose).

Example: instead of ("ordinary" case)

GET /path/to/myfile.html HTTP/1.1
Host: www.somehost.com

you have (pipelining)

GET /path/to/myfile.html HTTP/1.1
GET /path/to/myNextFile.html HTTP/1.1
GET /path to/yetAnotherFile.html HTTP/1.1
Host: www.somehost.com


I also do not know how well supported this is by Servers :-).

Regards,
Stephen


Stephen

unread,
Feb 2, 2003, 10:18:14 PM2/2/03
to
Gordan wrote:
>

snip lots...


>
>
> Ah, so that's where I've been missing. I wasn't aware of the asynchronous
> mode. Thanks. That is most useful. I don't suppose you know if there is a
> way to do something similar in Mozilla?
>
>

I believe Mozilla has async mode only, no synchronous...

Stephen

Jim Ley

unread,
Feb 3, 2003, 7:14:28 AM2/3/03
to
On Sun, 02 Feb 2003 13:43:03 +0000, Gordan <gor...@bobich.net> wrote:

>Steve van Dongen wrote:
>
>> Sounds like you should look into XMLHTTP
>> http://jibbering.com/2002/4/httprequest.html
>
>Thank for the reply, Steve.
>
>I am already aware of the XMLHTTP method for downloading things.
>Unfortunately, it only allows the download of one file at a time, which is
>why I was looking for a different solution that allows me to download
>multiple files simultaneously.

No it doesn't, I regularly download many things in paralell, just
create another XMLHTTP object, of course, you have to be doing this
async, but then there's no other choice on the web anyway.

Jim.

Jim Ley

unread,
Feb 3, 2003, 7:15:53 AM2/3/03
to
On Mon, 03 Feb 2003 03:18:14 GMT, Stephen <ssa...@austin.rr.com>
wrote:

synch is there unfortunately...

Jim.

Brendan Eich

unread,
Feb 6, 2003, 12:02:22 PM2/6/03
to Douglas Crockford
Douglas Crockford wrote:

>>Using Java/LiveConnect is precisely what I was trying to avoid... :-(
>>
>>
>
>That is most wise.
>
>
>
>>I take it that both SpiderMonkey and Rhino only provide a single-threading
>>environment?
>>

The answer to this question is "no" -- both SpiderMonkey and Rhino
support multi-threaded embeddings. The DOM implementation in Mozilla is
not one of them; nor does any DOM expose threading to script authors.
There is no ECMA standard for threads, locking, etc.

/be

Fotios

unread,
Feb 7, 2003, 7:40:47 AM2/7/03
to

>
> If you use asyncronous mode you can download as many files as you
> want. True, on a strictly technical level, the callbacks will be
> processed syncronously because javascript is single threaded, but
> there's nothing you can do about that and you'll have that problem
> with any solution that involves javascript.
> http://msdn.microsoft.com/library/en-us/xmlsdk/htm/xml_mth_or_4to4.asp
>
> The other thing to consider is that the HTTP 1.0 and 1.1
> specifications allows for four and two socket connections respectively
> per server, per process. You can spawn 100 threads and make 100
> requests if you want; however, all but 4/2 will be blocked unless they
> are made in different processes. There is a registry key that you can
> set to increase the client-side limit but, if I remember right,
> neither cannot be set higher than 16.
> http://support.microsoft.com/default.aspx?scid=kb;en-us;183110
>
> I use XMLHTTP along with setTimeout and setInterval in my pages -- I
> make 10-15 requests every 5 seconds or so -- and it works really
> nicely. I'm on an intranet with a responsive server though so the
> HTTP limit doesn't really affect me. If you're developing for an
> internet site you might have some trouble because of the higher
> latency.

The above, along with the post about many http servers allowing only 2
connections per client IP, is all excellent and accurate advice.

The other thing to consider is that xmlhttp may not allow or prompt the user
when out of domain access is attempted (access to domains other than the one
the current page belongs to).

Applets are still prone to such security restrictions but they can overcome
them by being signed.

Good luck,

Fotios
http://www.nkd-webmedia.co.uk/


0 new messages