Re: [whatwg] Workers feedback
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.