Re: [whatwg] Workers feedback

2008-08-08 Thread Ian Hickson

I've made createWorker() and createNamedWorker() return Worker objects 
with a 'port' attribute that represents the original message port.

I've removed the 'utils' object and put all the APIs back onto the global 
scope.

I've changed importScript() to importScripts() and made it take any number 
of URLs.

I've made unload be fired in a worker when the worker's lifetime expires.


On Wed, 6 Aug 2008, Chris Prince wrote:

 I'll try to write up some more detailed comments later, but for the 
 question above about a 'name' parameter and overoading:
 
 My current thinking is that the best API design for createWorker() is:
MessagePort createWorker(worker_body, [WorkerOptions])
 
 The reason: workers are a powerful concept, and it's very likely we'll 
 want to extend them over time.

I agree in general, but I think named workers are an important enough 
distinction that it's worth a second constructor.


 I'd say other options are likely to be just as 'important' as name, so I 
 wouldn't special-case that parameter.  A 'WorkerOptions' parameter 
 supports naming, but future expansion as well.

name is pretty important, I don't know of anything other than the URL of 
the script that I would say is more important.



On Thu, 7 Aug 2008, Chris Prince wrote:
 
 It is short-sighted to expect you can fully spec something as large as 
 workers.  This is a significant new concept, and we are only scratching 
 the surface.
 
 So why back ourselves into a corner?  Let's be smart about the API 
 design, and allow for future flexibility.
 
 I don't see any downsides to the approach outlined above.  If you have 
 something specific in mind, please let us know.

There's no downside per se, it's just not neccessary at this point. We can 
always add more arguments later, including one for a lot of optional 
parameters should we decide we need an object to do that.


On Thu, 7 Aug 2008, Jonas Sicking wrote:

 [utils]
 
 I don't feel very strongly about this right now. It's something we 
 started debating at mozilla and I think we'll debate it a bit more 
 before coming to a conclusion. I'm fine with putting it in the global 
 scope for now. Sorry, i didn't mean to ask for an immediate action on 
 this yet.

You said things were urgent, I assumed I should act on all your requests. :-)


 One solution I thought about is to have a base interface such as:
 
 interface MessagePort {
   void postMessage(...);
   attribute EventListener onmessage;
   ...
 }
 
 Then have
 
 interface Worker : MessagePort {
bool isShared();
worker specific stuff
 }
 
 interface PipePort : MessagePort {
attribute Window ownerWindow;
Pipe specific stuff
 }
 
 
 And then make the APIs that we want to allow passing around pipe-ends take a
 PipePort object.
 
 The result is basically that workers are separate objects from what's 
 returned for (new MessagePipe()).port1, but they share some API.

The problem there though is that when you receive a port, you have no idea 
if it's a port into another frame, or a port into a worker that happened 
to be created as a pipe, or a port into a worker that happened to be 
created when the worker was created. I don't see why you would ever need 
to have that distinction, either. The whole point of ports as an 
architectural concept is that they provide an opaque interface, and who 
exactly is on the other side is not something that you should need to have 
any information about.

In the design in the spec now, there's a Worker object that has 'load', 
'error', and 'unload' events on, which fire at the appropriate times in 
the lifetime of the worker, and there's a .pipe attribute that provides a 
pipe into the worker.


 [importScripts()]

 Yes. Another thing is that this function should probably return void and 
 always throw if something goes wrong. I doubt that having the server 
 return a 404 is expected enough that just returning 'false' will keep 
 the program executing fine.

Ok.


On Thu, 7 Aug 2008, Jonas Sicking wrote:
 
 To add to the above point, while the MessagePort API currently aligns 
 with the proposed Worker API, this seems likely to change in the future, 
 for example to test if a worker is shared between multiple frames.

I don't see why we'd ever do this, but I do see other things we might want 
to do to control a worker, e.g. close it or throttle it.


 I in general am not a big fan of the MessagePort API, the whole cloning 
 and dying thing is really ugly. I don't think there is much we can do 
 about that, but because of it I think we should only use the API when 
 it's strictly needed, which seems to be only in fairly complex usecases. 

I don't really understand this concern. Why is it complex? Then again, I 
have the same reaction to your proposal for a Worker object. :-)


 Exposing a MessagePort as a permanent property, like the global 'port' 
 property, has the downside that that object can potentially die if the 
 MessagePort is ever passed through postMessage 

Re: [whatwg] Workers feedback

2008-08-08 Thread Jonas Sicking

One solution I thought about is to have a base interface such as:

interface MessagePort {
  void postMessage(...);
  attribute EventListener onmessage;
  ...
}

Then have

interface Worker : MessagePort {
   bool isShared();
   worker specific stuff
}

interface PipePort : MessagePort {
   attribute Window ownerWindow;
   Pipe specific stuff
}


And then make the APIs that we want to allow passing around pipe-ends take a
PipePort object.

The result is basically that workers are separate objects from what's 
returned for (new MessagePipe()).port1, but they share some API.


The problem there though is that when you receive a port, you have no idea 
if it's a port into another frame, or a port into a worker that happened 
to be created as a pipe, or a port into a worker that happened to be 
created when the worker was created. I don't see why you would ever need 
to have that distinction, either.


Sorry, I might have been unclear. My suggested inheritance might be 
better explained as


interface CommunicationPort {
  void postMessage(...)
  attribute EventListener onmessage;
  ...
}

interface Worker : CommuncationPort {
  attribute EventListener onload;
  attribute EventListener onerror;
}

interface MessagePort : CommunicationPort {
}

I.e. we wouldn't allow a Worker to be passed to postMessage, but the 
object returned from myPipe.port1 would be allowed.


The whole point of ports as an 
architectural concept is that they provide an opaque interface, and who 
exactly is on the other side is not something that you should need to have 
any information about.


Why do we need this feature? I.e. why is it useful to have an abstracted 
MessagePort where you don't know who you are communicating with?


The one useful thing that I see that MessagePorts do is that they allow 
objects that usually can't directly reach each other send messages to 
each other. I.e. two iframes that live next to each other can't usually 
get a reference to each other, but using MessagePorts a communcation 
channel can be negotiated between them.


Similarly, two sibling workers can't in the current proposal reach each 
other, but using MessagePorts they can communicate with each other anyway.


I in general am not a big fan of the MessagePort API, the whole cloning 
and dying thing is really ugly. I don't think there is much we can do 
about that, but because of it I think we should only use the API when 
it's strictly needed, which seems to be only in fairly complex usecases. 


I don't really understand this concern. Why is it complex? Then again, I 
have the same reaction to your proposal for a Worker object. :-)


My proposal makes Workers behave the same way as Windows when it comes 
to sending messages. I think postMessage on Windows can generally be 
considered a success, I haven't heard a lot of people complaining about 
it being complex.


Exposing a MessagePort as a permanent property, like the global 'port' 
property, has the downside that that object can potentially die if the 
MessagePort is ever passed through postMessage somewhere.


Do you mean that:

   var w = createWorker('worker.js');
   otherWindow.postMessage('here is the worker you asked for', w.port);
   w.port.postMessage('oh i wanted to talk to you after all');

...would fail? (It would return false from the last call.)


Yes.

Further, the fact that a clone is created on the other end rather than 
the same object I think can be confusing. I.e. if I set an expando on a 
port the receiver of the port won't see the expando. This is required 
since otherwise we'd have synchronous communication between threads, but 
I think it's confusing to authors. This is why I generally don't like 
MessagePorts and think that they should be used as little as possible.


Also, I would have expected the above to throw an exception. Having it 
silently fail (which is what'll happen if you don't check the return 
value) seems likely to cause hidden bugs.


I don't think this is a big problem. I mean, it's like being worried that 
references into a window fail to have the right effect after the window is 
closed or navigated.


I think for windows we are usually saved by the fact that generally when 
a window is navigated, all the code that uses that window is killed.


This leaves the user with a permanent property containing a dead useless 
object. Not exposing it as a permanent property forces things like the 
onconnect event and returning a MessagePort from createWorker.


Do you mean on the Worker (outside) or the WorkerGlobalScope (inside)?


Yes

The current spec doesn't expose 'port' as a permanent attribute on the 
WorkerGlobalScope (inside), it's just a property added to the global 
object, it's not NoDelete or anything.


Hmm.. pretty much all other properties that are created by a browser is 
permanent. So I don't expect that this will change as far as user 
expected behavior goes.


I have yet to actually see any advantages to demanding the use of 

Re: [whatwg] Workers feedback

2008-08-08 Thread Ian Hickson
On Fri, 8 Aug 2008, Jonas Sicking wrote:
 
 I.e. we wouldn't allow a Worker to be passed to postMessage, but the 
 object returned from myPipe.port1 would be allowed.

I strongly disagree with the idea of making communication channels with 
workers be a second class citizen in terms of being able to send 
communication channels about.


  The whole point of ports as an architectural concept is that they 
  provide an opaque interface, and who exactly is on the other side is 
  not something that you should need to have any information about.
 
 Why do we need this feature? I.e. why is it useful to have an abstracted 
 MessagePort where you don't know who you are communicating with?

It is a critical component of any capabilities granting mechanism.


 My proposal makes Workers behave the same way as Windows when it comes 
 to sending messages.

That's the problem. The Window communication mechanism is a pretty crappy 
one -- it's a single channel, there's no delegation, if you want to 
connect two windows who don't know about each other you have to proxy, 
etc. If it wasn't for the fact that everyone is implementing it, I'd 
really be pushing for changing to a more capable (and more secure) system, 
something much more akin to message channels.

(I originally came up with postMessage() years ago, I have learnt much in 
that time about how message passing mechanisms should work.)


   Exposing a MessagePort as a permanent property, like the global 
   'port' property, has the downside that that object can potentially 
   die if the MessagePort is ever passed through postMessage somewhere.
  
  Do you mean that:
  
 var w = createWorker('worker.js');
 otherWindow.postMessage('here is the worker you asked for', w.port);
 w.port.postMessage('oh i wanted to talk to you after all');
  
  ...would fail? (It would return false from the last call.)
 
 Yes.
 
 Further, the fact that a clone is created on the other end rather than 
 the same object I think can be confusing. I.e. if I set an expando on a 
 port the receiver of the port won't see the expando. This is required 
 since otherwise we'd have synchronous communication between threads, but 
 I think it's confusing to authors. This is why I generally don't like 
 MessagePorts and think that they should be used as little as possible.

I disagree, but I don't know what I can say to convince you. All I can say 
is that the original impetus for the message channel mechanism came from 
authors who wanted a more capable messaging mechanism.


 Also, I would have expected the above to throw an exception. Having it 
 silently fail (which is what'll happen if you don't check the return 
 value) seems likely to cause hidden bugs.

Throwing an exception seems a little drastic, but I could be convinced to 
change that -- the problem is that there's no way to know if it's going to 
throw (or return false) before the call. Which is better?:

   if (!p.postMessage(msg)) {
 // it went away
   }

...or:

   try {
  p.postMessage(msg);
   } catch (e) {
  if (e.code == 20) {
// it went away
  }
   }

...?

Consider also that the postMessage() might not be critical, e.g.:

   // this code runs when the user asks to save his work
   for each (var p in registeredNotifiers) {
 // registeredNotifiers is a list of ports to parts of
 // the codebase that want to be notified just before
 // something is saved
 p.postMessage(msg);
   }
   doSave();

If the author doesn't check for the potential exceptions (which at the 
time of writing he might not be expecting, since he doesn't know if anyone 
is ever going to be doing something with the ports that would cause an 
exception to be possible here), then the saving doesn't work. If we just 
return false, then the error is ignored, which is likely fine here.


  I don't think this is a big problem. I mean, it's like being worried 
  that references into a window fail to have the right effect after the 
  window is closed or navigated.
 
 I think for windows we are usually saved by the fact that generally when 
 a window is navigated, all the code that uses that window is killed.

Not if it's in another window. I think it's very much the same problem.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Scripted querying of video capabilities

2008-08-08 Thread Tim Starling
Jeremy Doig wrote:
 how would this work (say) for different avc profile levels and
 features (eg: PAFF support) ?

I don't think that's our problem. The details of determining a type name
for a given file should be in another standard, it should not be in HTML
5. All HTML 5 has to do is delegate responsibility for type assignment.

 would we require video creators to know the specific capabilities of
 every fourCC target ?

Video creators aren't *required* to do anything. They can just embed
their videos in HTML with no specified type and test it on a few
platforms to see if it works.

The point of the interface (from my point of view) is to assist website
designers when they wish to promulgate a new or unpopular video format.
Presumably, the website designer will know the new video format very
well, otherwise they wouldn't bother.

-- Tim Starling


Re: [whatwg] Scripted querying of video capabilities

2008-08-08 Thread Tim Starling
Dave Singer wrote:
 I think this is a good idea, but one rapidly runs into the problems
 talked about in the 'bucket' RFC, notably that there is not a
 universal language for naming codecs (4ccs etc).  But it's proved
 useful in the past.

 In general, the source fallbacks are also a way to 'probe' this,
 albeit in a very different way.

 I'm not sure you can always get a definitive answer to the question
 if I gave you a file with this (extended) MIME type, could you play
 it? and I am fairly sure that asking the implementation to enumerate
 all the types it could support would be hard.

If you can't get an answer to that question, then how will the browsers
implement source fallbacks? What I'm suggesting is basically the same,
except without the requirement to download a video file.

All the issues with type names are also present with source.

-- Tim Starling


Re: [whatwg] Workers feedback

2008-08-08 Thread Jonas Sicking

So the API I'm proposing is the following:

[NoInterfaceObject] interface WorkerFactory {
   Worker createWorker(in DOMString scriptURL);
   Worker createSharedWorker(in DOMString name, in DOMString scriptURL);
};


interface Worker {
   boolean postMessage(in DOMString message);
   boolean postMessage(in DOMString message,
   in MessagePort messagePort);

   // event handler attributes
attribute EventListener onmessage;
attribute EventListener onload;
attribute EventListener onerror;
attribute EventListener onunload;
};

interface WorkerParent {
   boolean postMessage(in DOMString message);
   boolean postMessage(in DOMString message,
   in MessagePort messagePort);
};

[NoInterfaceObject] interface WorkerGlobalScope {
   // core worker features
   readonly attribute WorkerGlobalScope self;
   readonly attribute WorkerLocation location;
   readonly attribute DOMString name;
   readonly attribute boolean closing;
   readonly attribute WorkerParent parent;
   void close();

   // event handler attributes
attribute EventListener onunload;
};

(We might want to add an onconnect property to WorkerGlobalScope, but it
doesn't seem strictly needed)

I think that it has the following advantages over the current draft spec:

* We don't expose users to MessagePort objects in the majority of
  scenarios.
* There is no permanent .port properties anywhere that would go dead if
  the port is passed somewhere.
* There is no need for pseudo properties anywhere (the port variable
  inside the WorkerGlobalScript)
* The current draft duplicates the onunload property on both the
  worker and its port. Not sure if this is needed or just a bug.
* All onX objects live on the same object rather than some living
  on the worker, some living on worker.port.

I'd be interested to hear what others think of this proposal.

/ Jonas


Re: [whatwg] Workers feedback

2008-08-08 Thread Ian Hickson
On Fri, 8 Aug 2008, Jonas Sicking wrote:

 So the API I'm proposing is the following:

This seems to be a strict subset of what the spec has now; the only 
difference being that there's no easy way to create a worker and then pass 
it to someone else to take care of, and there seems to be no easy way for 
a worker to hear about a new parent.

 (We might want to add an onconnect property to WorkerGlobalScope, but it 
 doesn't seem strictly needed)

How else would you connect to a shared worker?


 I think that it has the following advantages over the current draft spec:
 
 * We don't expose users to MessagePort objects in the majority of
   scenarios.

I do not consider this an advantage. All we're doing is moving the 
complexity to a later point -- instead of learning part of the API and 
then more of the API if they want to, authors have to learn two APIs, one 
of which is just as complicated as today's, and another that is not quite 
the same as either Window.postMessage() or port.postMessage() but is 
similar enough to get them confused.


 * There is no permanent .port properties anywhere that would go dead if
   the port is passed somewhere.

The .parent property is as likely to go dead, e.g. if the parent goes away 
after the worker has been provided a port to another window.


 * There is no need for pseudo properties anywhere (the port variable
   inside the WorkerGlobalScript)

Replacing 'port' with 'parent' doesn't really change much. :-)


 * The current draft duplicates the onunload property on both the
   worker and its port. Not sure if this is needed or just a bug.

It's not strictly needed but it's useful to distinguish the death of the 
port from the death of the worker.


 * All onX objects live on the same object rather than some living
   on the worker, some living on worker.port.

They still also live on .port, it's just that you're not exposing this 
explicitly now. This is a false simplification IMHO.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Workers feedback

2008-08-08 Thread Jonas Sicking

Ian Hickson wrote:

On Fri, 8 Aug 2008, Jonas Sicking wrote:

So the API I'm proposing is the following:


This seems to be a strict subset of what the spec has now; the only 
difference being that there's no easy way to create a worker and then pass 
it to someone else to take care of, and there seems to be no easy way for 
a worker to hear about a new parent.


Don't really think it's a subset or a superset. The same feature set 
exists in both proposals, the syntax is just different.


The idea is that it's a simpler syntax for the common cases. However I 
think we'll have to agree to disagree what is simple at this point.


(We might want to add an onconnect property to WorkerGlobalScope, but it 
doesn't seem strictly needed)


How else would you connect to a shared worker?


That is done at an application level. For example:

worker = createSharedWorker(foo, bar.js);
worker.addEventListener(message, handler, false);
worker.postMessage(wassup dude, i just connected);

Actually, it seems like onconnect as defined in the current spec has a 
race condition. The shared worker example does the following:


   var worker = createSharedWorker('worker.js', 'core');
   function configure(event) {
 if (event.message.substr(0, 4) != 'cfg ') return;
 var name = event.message.substr(4).split(' ', 1);
 // update display to mention our name is name
 document.getElementsByTagName('h1')[0].textContent += ' ' + name;
 // no longer need this listener
 worker.port.removeEventListener('message', configure, false);
   }
   worker.port.addEventListener('message', configure, false);

However what's to say that the 'connect' event hasn't fired inside the 
worker before the 'worker.port.addEventListener' line executes? Note 
that there can already be other listeners to the port, so the port has 
been activated.


Also, what MessagePort object is handed to the connect event if the 
inner or outer port has been handed through postMessage somewhere? I.e. 
if someone does:


var worker = createSharedWorker('worker.js', 'core');
someIframe.postMessage(here's your worker, worker.port);

Does that mean that noone can ever share that worker again? And that 
anyone else currently sharing that worker is going to break?


I would have expected sharing workers would always set up new message 
pipes. So here's my revised proposal:



[NoInterfaceObject] interface WorkerFactory {
   Worker createWorker(in DOMString scriptURL);
   Worker createSharedWorker(in DOMString name, in DOMString scriptURL);
};


interface Worker {
   boolean postMessage(in DOMString message);
   boolean postMessage(in DOMString message,
   in MessagePort messagePort);

   MessagePort connectNewPipe();

   // event handler attributes
attribute EventListener onmessage;
attribute EventListener onload;
attribute EventListener onerror;
attribute EventListener onunload;
};

interface WorkerParent {
   boolean postMessage(in DOMString message);
   boolean postMessage(in DOMString message,
   in MessagePort messagePort);
};

[NoInterfaceObject] interface WorkerGlobalScope {
   // core worker features
   readonly attribute WorkerGlobalScope self;
   readonly attribute WorkerLocation location;
   readonly attribute DOMString name;
   readonly attribute boolean closing;
   readonly attribute WorkerParent parent;
   void close();

   // event handler attributes
attribute EventListener onunload;
attribute EventListener onconnect;
};


The change from previous version is the Worker.connectNewPipe function. 
When that function is called, two entangled MessagePorts are created. 
One is returned from the function, and one is provided to the code 
inside the worker by firing a 'connect' event which contains the port. 
Note that calling createSharedWorker does not fire a 'connect' event.


/ Jonas


Re: [whatwg] Workers feedback

2008-08-08 Thread Ian Hickson
On Fri, 8 Aug 2008, Jonas Sicking wrote:
   
   (We might want to add an onconnect property to WorkerGlobalScope, 
   but it doesn't seem strictly needed)
  
  How else would you connect to a shared worker?
 
 That is done at an application level. For example:
 
 worker = createSharedWorker(foo, bar.js);
 worker.addEventListener(message, handler, false);
 worker.postMessage(wassup dude, i just connected);

How would the worker distinguish that from the original parent sending 
the same message?


 Actually, it seems like onconnect as defined in the current spec has a 
 race condition. The shared worker example does the following:
 
var worker = createSharedWorker('worker.js', 'core');
function configure(event) {
  if (event.message.substr(0, 4) != 'cfg ') return;
  var name = event.message.substr(4).split(' ', 1);
  // update display to mention our name is name
  document.getElementsByTagName('h1')[0].textContent += ' ' + name;
  // no longer need this listener
  worker.port.removeEventListener('message', configure, false);
}
worker.port.addEventListener('message', configure, false);
 
 However what's to say that the 'connect' event hasn't fired inside the 
 worker before the 'worker.port.addEventListener' line executes?

Doesn't matter. MessagePorts queue up messages until they receiver either 
sets onmessage or calls start(). (This is explained just below the 
example.)


 Note that there can already be other listeners to the port, so the port 
 has been activated.

The port only activates if you set onmessage or call start(). Calling 
addEventListener() doesn't activate it.


 Also, what MessagePort object is handed to the connect event if the 
 inner or outer port has been handed through postMessage somewhere? I.e. 
 if someone does:
 
 var worker = createSharedWorker('worker.js', 'core');
 someIframe.postMessage(here's your worker, worker.port);
 
 Does that mean that noone can ever share that worker again?

The createSharedWorker() call always creates a new pipe to hand to the 
'connect' event.


 And that anyone else currently sharing that worker is going to break?

Why would it break anything? I'm confused.


 I would have expected sharing workers would always set up new message 
 pipes.

It does.


 So here's my revised proposal:

Now it's even more complicated, while still not doing everything that the 
current proposal does. I'm not at all convinced this is better.

Is the only problem you have with the current design that it is too 
complicated?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


[whatwg] Active workers when user leaves the page

2008-08-08 Thread Jonas Sicking
This is something that have been in the back of my brain for a few days: 
How do we deal with the user navigating a way from a page if there's a 
Worker in the middle of some very long running script?


First off, please notice that this discussion is 100% orthogonal to the 
communications API discussion that is ongoing in another thread. I don't 
want to get the two mixed up.


We don't really want to always allow a worker to finish working, even if 
the user leaves the only page that is currently using the worker. I.e. 
if someone has an infinite loop (by accident or intentionally), I don't 
think we want to leave that running until the user shuts down the 
browser. In fact, the user could very well be leaving the page because 
he/she feels that it is sucking up too much CPU power.


One possible solution is to simply set the .closing flag inside the 
worker and hope that the worker will honor that flag and break out ASAP. 
The UA could even at that point give the worker some set amount of time 
before forcefully killing the worker. We have a concept of a 'slow 
script' dialog in firefox that we use if scripts on the main thread take 
too long to run. The dialog asks the user if he/she wants to continue 
running the current script, or forcefully break it.


This will not usually be used for workers (the whole point is that they 
take a long time to finish), but we could engage it once the user tries 
to leave the page.


I do want to be agressive with killing workers when the user leaves a 
page since that makes for better user experience. However I'm also 
worried about stopping scripts halfway through breaking things and 
leaving the site with half-finished operations that are stored in 
databases or localStorage.


Also note that the the presence, or lack of, fastback cache doesn't 
really make a difference. Pages are eventually going to get purged from 
the fastback cache, so it just pushes the problem to a point a little 
later in time.



How has gears dealt with this problem so far? What are your experiences 
with it?


/ Jonas


Re: [whatwg] Workers feedback

2008-08-08 Thread Jonas Sicking

Ian Hickson wrote:

On Fri, 8 Aug 2008, Jonas Sicking wrote:
(We might want to add an onconnect property to WorkerGlobalScope, 
but it doesn't seem strictly needed)

How else would you connect to a shared worker?

That is done at an application level. For example:

worker = createSharedWorker(foo, bar.js);
worker.addEventListener(message, handler, false);
worker.postMessage(wassup dude, i just connected);


How would the worker distinguish that from the original parent sending 
the same message?


Why would the original parent same the message twice? Of course 
applications following their own application level protocols is going to 
break themselves.


Actually, it seems like onconnect as defined in the current spec has a 
race condition. The shared worker example does the following:


   var worker = createSharedWorker('worker.js', 'core');
   function configure(event) {
 if (event.message.substr(0, 4) != 'cfg ') return;
 var name = event.message.substr(4).split(' ', 1);
 // update display to mention our name is name
 document.getElementsByTagName('h1')[0].textContent += ' ' + name;
 // no longer need this listener
 worker.port.removeEventListener('message', configure, false);
   }
   worker.port.addEventListener('message', configure, false);

However what's to say that the 'connect' event hasn't fired inside the 
worker before the 'worker.port.addEventListener' line executes?


Doesn't matter. MessagePorts queue up messages until they receiver either 
sets onmessage or calls start(). (This is explained just below the 
example.)


Note that there can already be other listeners to the port, so the port 
has been activated.


The port only activates if you set onmessage or call start(). Calling 
addEventListener() doesn't activate it.


Ah, i missed the fact that calling createSheredWorker always created a 
new Worker object, even if one already existed.


/ Jonas


Re: [whatwg] Workers feedback

2008-08-08 Thread Jonas Sicking

Jonas Sicking wrote:

Ian Hickson wrote:

On Fri, 8 Aug 2008, Jonas Sicking wrote:
(We might want to add an onconnect property to WorkerGlobalScope, 
but it doesn't seem strictly needed)

How else would you connect to a shared worker?

That is done at an application level. For example:

worker = createSharedWorker(foo, bar.js);
worker.addEventListener(message, handler, false);
worker.postMessage(wassup dude, i just connected);


How would the worker distinguish that from the original parent 
sending the same message?


Why would the original parent same the message twice? Of course 
applications following their own application level protocols is going to 
break themselves.


Sorry, that should say: Of course applications *not* following their own 
application level protocols are going to break themselves.


/ Jonas


Re: [whatwg] Workers feedback

2008-08-08 Thread Ian Hickson
On Fri, 8 Aug 2008, Jonas Sicking wrote:
  
   worker = createSharedWorker(foo, bar.js);
   worker.addEventListener(message, handler, false);
   worker.postMessage(wassup dude, i just connected);
  
  How would the worker distinguish that from the original parent 
  sending the same message?
 
 Why would the original parent same the message twice? Of course 
 applications following their own application level protocols is going to 
 break themselves.

The whole point of capabilities-based systems is that you can pass these 
communcation ports over to unknown entities and don't have to trust that 
they won't screw up your protocol. For example, you could create a shared 
worker to handle all the requests from all the gadgets hosted on a user's 
home page and just pass the worker off to them each time:

   // a new gadget has been created
   var worker = createSharedWorker('gadget-api.js', 'gadgets');
   gadget.postMessage('here is the gadget API', worker.port);

What you're proposing would be way more complex -- now you'd have to 
create the pipe separately, you'd have to have the worker know how to 
handle both a new connection from its parent as well as its parent saying 
it wants a new pipe for a gadget, you'd have lifetime issues as you 
now have extra commucation mechanisms, etc.

(This brings up another point, which is that by having Worker objects also 
be communication end points, we double the complexity of the definitions 
for worker lifetime, since now they have to deal with both types of 
channels, not just the one generic type.)

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Active workers when user leaves the page

2008-08-08 Thread Ian Hickson
On Fri, 8 Aug 2008, Jonas Sicking wrote:

 This is something that have been in the back of my brain for a few days: 
 How do we deal with the user navigating a way from a page if there's a 
 Worker in the middle of some very long running script?

Right now the spec says that closing becomes true, and if the worker 
doesn't clean up promptly, the kill a worker algorithm is invoked and 
the script is killed, the unload handler is handled, and the script is 
killed again if that doesn't end prompty either.


 Also note that the the presence, or lack of, fastback cache doesn't 
 really make a difference. Pages are eventually going to get purged from 
 the fastback cache, so it just pushes the problem to a point a little 
 later in time.

Yup, the spec deals with this already too.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Active workers when user leaves the page

2008-08-08 Thread Robert O'Callahan
On Sat, Aug 9, 2008 at 7:01 AM, Jonas Sicking [EMAIL PROTECTED] wrote:

 I do want to be agressive with killing workers when the user leaves a page
 since that makes for better user experience. However I'm also worried about
 stopping scripts halfway through breaking things and leaving the site with
 half-finished operations that are stored in databases or localStorage.


Aggressive killing of workers without warning when the user navigates away
would actually be a good feature.

There are various reasons outside anyone's control that a worker might die
abruptly. For example, power failure, browser crash, or slow-script style
timeout. Applications need to be able to handle those cases, for example by
using database transactions or careful use of atomic operations. But that's
hard to test and authors probably won't design or test well for those cases
since they're relatively uncommon. Expanding abrupt termination scenarios to
include navigate-away makes abrupt termination much easier to test, forces
authors to design for it early, and will ultimately simplify the application
design by reducing the different ways a worker can terminate.

This may sound a bit radical, but it's not a new idea. It's a principle
sometimes called crash-only software. See e.g.
http://www.usenix.org/events/hotos03/tech/full_papers/candea/candea_html/

Rob
-- 
He was pierced for our transgressions, he was crushed for our iniquities;
the punishment that brought us peace was upon him, and by his wounds we are
healed. We all, like sheep, have gone astray, each of us has turned to his
own way; and the LORD has laid on him the iniquity of us all. [Isaiah
53:5-6]


Re: [whatwg] Active workers when user leaves the page

2008-08-08 Thread Martin Ellis
Hi,

 

Could it not be set that a there is a maximum execution time for any workers 
that are still active, definable by the browser but with a suggested value of 
say 1000milliseconds in the spec, any processing that takes longer than this is 
killed, but gives the option for well built scripts and cleanup processes to 
run gracefully.

 

Martin

 

From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Robert O'Callahan
Sent: 08 August 2008 23:30
To: Jonas Sicking
Cc: whatwg
Subject: Re: [whatwg] Active workers when user leaves the page

 

On Sat, Aug 9, 2008 at 7:01 AM, Jonas Sicking [EMAIL PROTECTED] wrote:

I do want to be agressive with killing workers when the user leaves a 
page since that makes for better user experience. However I'm also worried 
about stopping scripts halfway through breaking things and leaving the site 
with half-finished operations that are stored in databases or localStorage.


Aggressive killing of workers without warning when the user navigates away 
would actually be a good feature.

There are various reasons outside anyone's control that a worker might die 
abruptly. For example, power failure, browser crash, or slow-script style 
timeout. Applications need to be able to handle those cases, for example by 
using database transactions or careful use of atomic operations. But that's 
hard to test and authors probably won't design or test well for those cases 
since they're relatively uncommon. Expanding abrupt termination scenarios to 
include navigate-away makes abrupt termination much easier to test, forces 
authors to design for it early, and will ultimately simplify the application 
design by reducing the different ways a worker can terminate.

This may sound a bit radical, but it's not a new idea. It's a principle 
sometimes called crash-only software. See e.g. 
http://www.usenix.org/events/hotos03/tech/full_papers/candea/candea_html/


Rob
-- 
He was pierced for our transgressions, he was crushed for our iniquities; the 
punishment that brought us peace was upon him, and by his wounds we are healed. 
We all, like sheep, have gone astray, each of us has turned to his own way; and 
the LORD has laid on him the iniquity of us all. [Isaiah 53:5-6]


-- 
This message has been scanned for viruses and 
dangerous content by MailScanner http://www.mailscanner.info/ , and is 
believed to be clean. 



[whatwg] CanvasRenderingContext2D::createPattern and partially loaded images

2008-08-08 Thread Eric Seidel
http://www.whatwg.org/specs/web-apps/current-work/#createpattern

Notes that:
The first argument gives the image to use as the pattern (either an
HTMLImageElement or an HTMLCanvasElement). Modifying this image after
calling the createPattern() method must not affect the pattern.

What does this mean for images which are not yet fully loaded from the
network?  Safari's current behavior is that the pattern will draw the
image with as much data as we know about that network resource *at the
time the pattern is drawn*.  Instead of at the time the pattern is
created (as the spec seems to imply).  Meaning if you're a web author,
and you don't bother to listen for Image load events, if your user is
on a slow network, each time you draw your pattern, you'll have
slightly more of the image until it completes.

I can disable this feature of Safari (make it so that
createPattern() creates a copy of the image, in whatever loaded
state it may be), or we can change the spec to say that incremental
loading images do not count as modifying the image after calling
createPattern().

Thoughts?

-eric


Re: [whatwg] CanvasRenderingContext2D::createPattern and partially loaded images

2008-08-08 Thread Eric Seidel
Nevermind:

If the image argument is an HTMLImageElement object whose complete
attribute is false, then the implementation must raise an
INVALID_STATE_ERR exception.

-eric

On Fri, Aug 8, 2008 at 5:03 PM, Eric Seidel [EMAIL PROTECTED] wrote:
 http://www.whatwg.org/specs/web-apps/current-work/#createpattern

 Notes that:
 The first argument gives the image to use as the pattern (either an
 HTMLImageElement or an HTMLCanvasElement). Modifying this image after
 calling the createPattern() method must not affect the pattern.

 What does this mean for images which are not yet fully loaded from the
 network?  Safari's current behavior is that the pattern will draw the
 image with as much data as we know about that network resource *at the
 time the pattern is drawn*.  Instead of at the time the pattern is
 created (as the spec seems to imply).  Meaning if you're a web author,
 and you don't bother to listen for Image load events, if your user is
 on a slow network, each time you draw your pattern, you'll have
 slightly more of the image until it completes.

 I can disable this feature of Safari (make it so that
 createPattern() creates a copy of the image, in whatever loaded
 state it may be), or we can change the spec to say that incremental
 loading images do not count as modifying the image after calling
 createPattern().

 Thoughts?

 -eric



Re: [whatwg] HTML 5 : Misconceptions Documented

2008-08-08 Thread Garrett Smith
On Thu, Aug 7, 2008 at 4:37 PM, Maciej Stachowiak [EMAIL PROTECTED] wrote:

 On Aug 7, 2008, at 3:44 PM, Garrett Smith wrote:


I'd like to put this back on the list, and it doesn't contain anything
personal, so I'm taking the liberty here.

 I'm not sure what you mean by in the binding.

I meant the EcmaScript binding.

 Do you mean in Web IDL's
 definition of how to map Web IDL interfaces to the ECMAScript language, or
 one-off in the HTML5 spec for every interface this applies to?

Narrowing the scope in the interest of not creating bugs seems like a
very good idea.

This could potentially be described in the EcmaScript bindings. But it
would be a good idea to explore some edge cases. Particularly, if the
case was the order of definition of properties: One such case would be
an HTMLCollection with an element named length. In that case, the
readonly length property would have to be the actual length of the
collection; the value should not be replaced with an element of that
name/id.

forminput name=length/form

document.forms[0].elements.length

Opera9: [object HTMLInputElement] -- BUG
FF3: 1
Saf3: 1

Another consideration would be a form element with an attribute
length. That would be a problem as neither the attribute, nor the
Netscape 4 DOM named items are specified as readonly. So that's
one reason for not specifying the Netscape 4 DOM and for removing that
example from WF 2.0
http://www.whatwg.org/specs/web-forms/current-work/#select-check-default


 I think the Web IDL spec should correctly define how to map Web IDL to
 ECMAScript, while not precluding the possibility of mapping to other
 languages.

It's a good idea to understand what is happening in the language we're
concerned with: EcmaScript implementations (browsers) are where the
phenomenon was noticed and from where the concern was raised.

Aren't [IndexGetter] and [ NameGetter] are really doing the same thing
in most cases?

Why differentiate between number properties and name properties?

Is added as properties an accurate description?

For example:
For each item in the collection object, a corresponsding property is
present on that object. The property's name is the ordinal index and
the value is the result of calling the collection's item() method.

From the Web IDL WD:
http://dev.w3.org/2006/webapi/WebIDL/#IndexGetter

| An ECMAScript implementation would have an internal [[Get]]
| method that allows values to be retrieved from the  map as
| properties, and a corresponding [[Put]] method for setting values
| in the map:
| ECMAScript
|
|  // Assume map is a host object implementing
| //  the OrderedMap interface.
| var map = getOrderedMap();
| var x, y;
|
| x = map[0]; // Same as: x = map.getByIndex(0)
| map[1] = false; // Same as: map.setByIndex(1, false)
|
| y = map.apple;  // Same as: y = map.get('apple')
| map.banana = 123;   // Same as: map.set('banana', 123)
`--

It seems that the expectation is that [[Get]] will differentiate
between and typecheck the Expression. This is not how property access
works. In the above, the Expression in map[0] is 0. This 0 is
converted to the string 0.

| The production MemberExpression :
| MemberExpression [ Expression  ] is evaluated as follows:
|
| 1. Evaluate MemberExpression.
| 2. Call GetValue(Result(1)).
| 3. Evaluate Expression.
| 4. Call GetValue(Result(3)).
| 5. Call ToObject(Result(2)).
| 6. Call ToString(Result(4)).

In step 4., we call GetValue(Result(3)

| 8.7.1 GetValue(V)
|
|  4.. If Type(V) is not Reference, return V.

Type V is not a reference, it is a Number, 0, so 0 is returned to
property access algorithm step 4. In step 6, property access calls
ToString(Result(4)),

| 9.8.1 ToString Applied to the Number Type

This is a little involved, and includes exponential notation, but the
result of ToString(0), will be 0,

map[0] has the same effect as map[0].

I don't know if any other languages have this functionality.

Now the same cannot be said for [[Put]] because Arrays have a special
[[Put]] method that does do some checking on the Expression. Array's
[[Put]] can change the length of the Array, or, if the property name
is 'length', can cause indexed properties to be deleted. Special
[[Put]] functionality might apply to the HTMLSelectElement, which in
all browsers will create/remove options when the length is changed.
However, a [NameSetter]  seems over the top.
http://dev.w3.org/2006/webapi/WebIDL/#NameSetter

!DOCTYPE HTML
html lang=en
head
titleMagic-Select [[Put]]/title
/head
body
formselect name=aaa/select/form
script
var a = document.forms[0].elements.aaa;
a.length = 12
a.options[3].text = pass;
a.selectedIndex = 3;
/script
/body
/html

Wouldn't it be better to just have a simple note in the HTML 5 spec
what happens when a Select's length property is set?

Garrett

 This may include hints that are relevant to ECMAScript but not
 for most other language bindings.