Re: [whatwg] Application defined locks
On Sep 9, 2009, at 10:12 PM, Aaron Boodman wrote: OTOH, it seems like showModalDialog() is just a sharp edge that is likely to hurt you no matter what. Even with your proposal, unless you carefully arranged things in preparation for showModalDialog(), you could get stuck the same way. showModalDialog is, in effect, a legacy API for largely intranet- deployed enterprise apps. It's not really used on the public Web or in modern content. If use of showModalDialog causes some suboptimal behavior (whether race conditions or needless event loop blockage), I won't lose too much sleep. Regards, Maciej
Re: [whatwg] cloneNode and HTML elements
On Sep 9, 2009, at 10:26 PM, Robert O'Callahan wrote: If you call cloneNode on a media element, the state of the resulting media element seems unspecified. Should it be playing the same media resource at the same current time as the original? Similar questions arise when you clone form elements; is the state that's not visible in the DOM cloned? Who should be responsible for defining this? Does cloneNode require copying any state besides an element's qualified name, attributes and DOM children? The definition in DOM3Core doesn't say anything else should be copied. Is form control state (such as set of items selected in a list multiple) copied? Reference for cloneNode: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-3A0ED0A4 My assumption based on the spec is that no element-specific internal state should be copied, the cloning should only be DOM-wise. Regards, Maciej
Re: [whatwg] cloneNode and HTML elements
On Thu, 10 Sep 2009 07:26:06 +0200, Robert O'Callahan rob...@ocallahan.org wrote: If you call cloneNode on a media element, the state of the resulting media element seems unspecified. Should it be playing the same media resource at the same current time as the original? Similar questions arise when you clone form elements; is the state that's not visible in the DOM cloned? Who should be responsible for defining this? Rob In my opinion, expecting the cloned MediaElement to retain all of its state is more work to implement and not really worth it. I don't know where it should be defined, but think the best behavior would be to just clone the content attributes. In other words, you'd get a media element in state NETWORK_EMPTY/HAVE_NOTHING which would start resource selection when you insert it into a document. -- Philip Jägenstedt Core Developer Opera Software
Re: [whatwg] cloneNode and HTML elements
On Thu, Sep 10, 2009 at 12:41 AM, Maciej Stachowiak m...@apple.com wrote: On Sep 9, 2009, at 10:26 PM, Robert O'Callahan wrote: If you call cloneNode on a media element, the state of the resulting media element seems unspecified. Should it be playing the same media resource at the same current time as the original? Similar questions arise when you clone form elements; is the state that's not visible in the DOM cloned? Who should be responsible for defining this? Does cloneNode require copying any state besides an element's qualified name, attributes and DOM children? The definition in DOM3Core doesn't say anything else should be copied. Is form control state (such as set of items selected in a list multiple) copied? Reference for cloneNode: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-3A0ED0A4 My assumption based on the spec is that no element-specific internal state should be copied, the cloning should only be DOM-wise. My assumption was always the opposite. For example for input elements we clone the 'value' API attribute, as well as the internal has-changed-value bit (used for form field restore when going back to a page). For script we copy over the has-executed bit. I'm fairly sure that the list is longer. / Jonas
Re: [whatwg] cloneNode and HTML elements
On 9/10/09 11:13 AM, Jonas Sicking wrote: On Thu, Sep 10, 2009 at 12:41 AM, Maciej Stachowiakm...@apple.com wrote: On Sep 9, 2009, at 10:26 PM, Robert O'Callahan wrote: If you call cloneNode on a media element, the state of the resulting media element seems unspecified. Should it be playing the same media resource at the same current time as the original? Similar questions arise when you clone form elements; is the state that's not visible in the DOM cloned? Who should be responsible for defining this? Does cloneNode require copying any state besides an element's qualified name, attributes and DOM children? The definition in DOM3Core doesn't say anything else should be copied. Is form control state (such as set of items selected in alist multiple) copied? Reference for cloneNode: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-3A0ED0A4 My assumption based on the spec is that no element-specific internal state should be copied, the cloning should only be DOM-wise. My assumption was always the opposite. For example forinput elements we clone the 'value' API attribute, as well as the internal has-changed-value bit (used for form field restore when going back to a page). Forscript we copy over the has-executed bit. I'm fairly sure that the list is longer. / Jonas I've always interpret DOM3 Core strictly; cloning an element clones the object and copies all attributes and their values So no state copying. (I noticed the input element state cloning when writing other cloning related stuff.) If we start to copy the state, there is the problem to define what all state should be cloned. Btw, DOM 3 Core defines it pretty badly what should be cloned when a document is cloned. cloning Document ... is implementation dependent If elements start to clone their state, should document do it too. Should document's stylesheets be cloned? And if stylesheets, what about .defaultView etc. ? -Olli
Re: [whatwg] cloneNode and HTML elements
On Thu, Sep 10, 2009 at 7:41 PM, Maciej Stachowiak m...@apple.com wrote: On Sep 9, 2009, at 10:26 PM, Robert O'Callahan wrote: If you call cloneNode on a media element, the state of the resulting media element seems unspecified. Should it be playing the same media resource at the same current time as the original? Similar questions arise when you clone form elements; is the state that's not visible in the DOM cloned? Who should be responsible for defining this? Does cloneNode require copying any state besides an element's qualified name, attributes and DOM children? The definition in DOM3Core doesn't say anything else should be copied. Is form control state (such as set of items selected in a list multiple) copied? Reference for cloneNode: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-3A0ED0A4 My assumption based on the spec is that no element-specific internal state should be copied, the cloning should only be DOM-wise. It's not obvious to me that DOM 3 Core's silence means nothing else is copied, since non-DOM state is outside its scope. I wonder if authors would be surprised if the non-DOM state is not copied. 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] cloneNode and HTML elements
On Thu, 10 Sep 2009 11:15:06 +0200, Robert O'Callahan rob...@ocallahan.org wrote: On Thu, Sep 10, 2009 at 7:41 PM, Maciej Stachowiak m...@apple.com wrote: On Sep 9, 2009, at 10:26 PM, Robert O'Callahan wrote: If you call cloneNode on a media element, the state of the resulting media element seems unspecified. Should it be playing the same media resource at the same current time as the original? Similar questions arise when you clone form elements; is the state that's not visible in the DOM cloned? Who should be responsible for defining this? Does cloneNode require copying any state besides an element's qualified name, attributes and DOM children? The definition in DOM3Core doesn't say anything else should be copied. Is form control state (such as set of items selected in a list multiple) copied? Reference for cloneNode: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-3A0ED0A4 My assumption based on the spec is that no element-specific internal state should be copied, the cloning should only be DOM-wise. It's not obvious to me that DOM 3 Core's silence means nothing else is copied, since non-DOM state is outside its scope. I wonder if authors would be surprised if the non-DOM state is not copied. I would suggest only copying state when it is needed for web compatibility or when there's a compelling use case. In the case of HTMLMediaElement the complexity of setting up a second decoding pipeline and trying to get it into the same state as the first must also be taken into account. A true clone may simply not be possible in all implementations. -- Philip Jägenstedt Core Developer Opera Software
Re: [whatwg] [html5] r3793 - [e] (0) noscript example
On Thu, 10 Sep 2009 13:17:37 +0200, wha...@whatwg.org wrote: Author: ianh Date: 2009-09-10 04:17:36 -0700 (Thu, 10 Sep 2009) New Revision: 3793 Modified: index source Log: [e] (0) noscript example Modified: source === --- source 2009-09-10 09:59:24 UTC (rev 3792) +++ source 2009-09-10 11:17:36 UTC (rev 3793) @@ -13454,8 +13454,40 @@ /div + div class=example + pIn the following example, a codenoscript/code element is + used to provide fallback for a script./p + prelt;form action=calcSquare.php + lt;p + lt;label for=xNumberlt;/label: + lt;input id=x name=x type=number + lt;/p + lt;script + var x = document.getElementById('x'); + var output = document.createElement('p'); + output.textContent = 'Type a number; it will be squared right then!'; + x.form.appendChild(output); + x.form.onsubmit = function () { return false; } + x.oninput = function () { +var v = x.valueAsNumber; +output.textContent = v + ' squared is ' + v * v; + }; + lt;/script + lt;noscript + lt;input type=submit value=Calculate Square + lt;/noscript +lt;/form/pre + + pWhen script is enabled, disabled. a button appears to do the calculation + on the server side. When script is enabled, the value is computed + on-the-fly instead./p + + /div Please add another example showing how to do the same thing without noscript (i.e. swapping the submit button for the output paragraph replaceChild). This is a better technique because noscript is unaware of whether the script was successful, and also noscript is not supported in XHTML. -- Simon Pieters Opera Software
Re: [whatwg] cloneNode and HTML elements
On Sep 10, 2009, at 2:15 AM, Robert O'Callahan wrote: On Thu, Sep 10, 2009 at 7:41 PM, Maciej Stachowiak m...@apple.com wrote: Reference for cloneNode: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-3A0ED0A4 My assumption based on the spec is that no element-specific internal state should be copied, the cloning should only be DOM-wise. It's not obvious to me that DOM 3 Core's silence means nothing else is copied, That's how I would tend to interpret its silence, unless some other spec says otherwise. But to be fair, a the DOM specs are sometimes vague on the details. For example, it doesn't explicitly say what localName, prefix or namespace a cloned element gets. Or that what text contents cloned Text nodes should have. since non-DOM state is outside its scope. DOM2 Core also defines cloneNode, and the associated DOM2 HTML does not impose any additional requirements for the HTML elements that have internal state. That would tend to support the theory that copying element-specific non-DOM state was not intended. I wonder if authors would be surprised if the non-DOM state is not copied. We haven't had any bug reports about it in WebKit, and we don't clone any internal state. We do have a bug report on cloneNode for Documents, where our choice of implementation-defined behavior is to return null. We'll likely have to fix that. My mental model of cloneNode is that it's equivalent to creating a brand new element with the right name and namespace, adding the appropriate attributes, and if a deep clone, copies of its children. So I would not be surprised. Others may have a different mental model. Regards, Maciej
Re: [whatwg] cloneNode and HTML elements
On Thu, 10 Sep 2009 13:57:03 +0200, Maciej Stachowiak m...@apple.com wrote: Indeed, we seem to copy the following things for form controls: value, checked state, indeterminate state. We don't seem to do anything special for any other elements. The change to clone form state was made based on this bug report: https://bugs.webkit.org/show_bug.cgi?id=5177 . The bug report cites Mozilla and IE behavior but does not mention a real-world site depending on this, though I would presume there was one. I think this behavior should be specified in HTML5. I guess that makes sense. Though I would personally prefer if we could move the HTML5 specific bits of DOM Core to Web DOM Core which then would simply state the exceptions for HTML documents. That way the methods are defined in one place which makes more sense to me. -- Anne van Kesteren http://annevankesteren.nl/
Re: [whatwg] cloneNode and HTML elements
On Sep 10, 2009, at 5:01 AM, Anne van Kesteren wrote: On Thu, 10 Sep 2009 13:57:03 +0200, Maciej Stachowiak m...@apple.com wrote: Indeed, we seem to copy the following things for form controls: value, checked state, indeterminate state. We don't seem to do anything special for any other elements. The change to clone form state was made based on this bug report: https://bugs.webkit.org/show_bug.cgi?id=5177 . The bug report cites Mozilla and IE behavior but does not mention a real-world site depending on this, though I would presume there was one. I think this behavior should be specified in HTML5. I guess that makes sense. Though I would personally prefer if we could move the HTML5 specific bits of DOM Core to Web DOM Core which then would simply state the exceptions for HTML documents. That way the methods are defined in one place which makes more sense to me. Is Web DOM Core official enough that HTML5 could normatively reference it yet? Once it has some standing, it might make sense to move HTML exceptions to DOM Core behavior there. Until then, I think it makes sense to define them in HTML5. Regards, Maciej
Re: [whatwg] cloneNode and HTML elements
On Thu, 10 Sep 2009 14:10:43 +0200, Maciej Stachowiak m...@apple.com wrote: Is Web DOM Core official enough that HTML5 could normatively reference it yet? Once it has some standing, it might make sense to move HTML exceptions to DOM Core behavior there. Until then, I think it makes sense to define them in HTML5. Fair enough. Seems we're still lacking someone to continue the work Simon started :/ -- Anne van Kesteren http://annevankesteren.nl/
Re: [whatwg] Application defined locks
On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.comwrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? 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] Application defined locks
On Sep 10, 2009, at 11:22 AM, Michael Nordman wrote: On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.org wrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.com wrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? How would the pages that failed to acquire it before know that they should try to acquire it again? Presumably they would still have to poll (assuming the tryLock model). Regards, Maciej
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 12:32 PM, Maciej Stachowiak m...@apple.com wrote: On Sep 10, 2009, at 11:22 AM, Michael Nordman wrote: On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.comwrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? How would the pages that failed to acquire it before know that they should try to acquire it again? Presumably they would still have to poll (assuming the tryLock model). Regards, Maciej In my proposed interace, you can wait asynchronously for the lock. Just call acquireLock with a second parameter, a closure that runs once you get the lock. -Darin
Re: [whatwg] Application defined locks
On Sep 10, 2009, at 12:55 PM, Darin Fisher wrote: On Thu, Sep 10, 2009 at 12:32 PM, Maciej Stachowiak m...@apple.com wrote: On Sep 10, 2009, at 11:22 AM, Michael Nordman wrote: On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.org wrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.com wrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? How would the pages that failed to acquire it before know that they should try to acquire it again? Presumably they would still have to poll (assuming the tryLock model). Regards, Maciej In my proposed interace, you can wait asynchronously for the lock. Just call acquireLock with a second parameter, a closure that runs once you get the lock. What if you don't want to wait asynchronously? My reading of this is that you need two copies of the code, one that works synchronously, but you still need to keep the asynchronous model to deal with an inability to synchronously acquire the lock. What am I missing? -Darin --Oliver
[whatwg] Typo: 'possibly' as adjective
[P]ossibly algorithms in the adoption agency algorithm note should be possible algorithms. -- Øistein E. Andersen
[whatwg] Initial carriage return in pre and textarea
§ 9.1.2.5 Restrictions on content models mentions that an initial line feed (\n) character inside pre and textarea will be removed. Should it not cover carriage return (\r) and \r\n as well? -- Øistein E. Andersen
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 1:08 PM, Oliver Hunt oli...@apple.com wrote: On Sep 10, 2009, at 12:55 PM, Darin Fisher wrote: On Thu, Sep 10, 2009 at 12:32 PM, Maciej Stachowiak m...@apple.com wrote: On Sep 10, 2009, at 11:22 AM, Michael Nordman wrote: On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.comwrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? How would the pages that failed to acquire it before know that they should try to acquire it again? Presumably they would still have to poll (assuming the tryLock model). Regards, Maciej In my proposed interace, you can wait asynchronously for the lock. Just call acquireLock with a second parameter, a closure that runs once you get the lock. What if you don't want to wait asynchronously? My reading of this is that you need two copies of the code, one that works synchronously, but you still need to keep the asynchronous model to deal with an inability to synchronously acquire the lock. What am I missing? Sounds like a problem that can be solved with a function. The reason for the trylock support is to allow a programmer to easily do nothing if they can't acquire the lock. If you want to wait if you can't acquire the lock, then using the second form of acquireLock, which takes a function, is a good solution. -Darin
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 12:32 PM, Maciej Stachowiak m...@apple.com wrote: On Sep 10, 2009, at 11:22 AM, Michael Nordman wrote: On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.comwrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? How would the pages that failed to acquire it before know that they should try to acquire it again? Presumably they would still have to poll (assuming the tryLock model). @Maciej, per darin's comment, that was the proposed interface my snippet was using. So no polling invovled. Probably hundreds of lines of js/sql code reduced to one. This would be a nice generally applicable primitive to have. Regards, Maciej
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 1:55 PM, Darin Fisher da...@chromium.org wrote: On Thu, Sep 10, 2009 at 1:08 PM, Oliver Hunt oli...@apple.com wrote: On Sep 10, 2009, at 12:55 PM, Darin Fisher wrote: On Thu, Sep 10, 2009 at 12:32 PM, Maciej Stachowiak m...@apple.comwrote: On Sep 10, 2009, at 11:22 AM, Michael Nordman wrote: On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.comwrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? How would the pages that failed to acquire it before know that they should try to acquire it again? Presumably they would still have to poll (assuming the tryLock model). Regards, Maciej In my proposed interace, you can wait asynchronously for the lock. Just call acquireLock with a second parameter, a closure that runs once you get the lock. What if you don't want to wait asynchronously? My reading of this is that you need two copies of the code, one that works synchronously, but you still need to keep the asynchronous model to deal with an inability to synchronously acquire the lock. What am I missing? Sounds like a problem that can be solved with a function. The reason for the trylock support is to allow a programmer to easily do nothing if they can't acquire the lock. If you want to wait if you can't acquire the lock, then using the second form of acquireLock, which takes a function, is a good solution. I don't think there is much value in the first form of acquireLock() - only the second form really makes sense. I also strongly feel that giving web developers access to locking mechanisms is a bad idea - it hasn't been a spectacular success in any other language. I think the useful semantics are equivalent to the following (being careful to avoid mentioning 'locks' or 'mutexes' explicit): A script passes in a callback and a token. The UA invokes the callback at some point in the future and provides the guarantee that no other callback with that token will be invoked in any context within the origin until the invoked callback returns. Here's what I mean with an intentionally horrible name: window.runMeExclusively(callback, arbitrary string token); An application developer could then put all of their logic that touches a particular shared resource behind a token. It's also deadlock free so long as each callback terminates. Would this be sufficient? If so it is almost possible to implement it correctly in a JavaScript library using a shared worker per origin and postMessage, except that it is not currently possible to detect when a context goes away. - James -Darin
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 2:38 PM, James Robinson jam...@google.com wrote: On Thu, Sep 10, 2009 at 1:55 PM, Darin Fisher da...@chromium.org wrote: On Thu, Sep 10, 2009 at 1:08 PM, Oliver Hunt oli...@apple.com wrote: On Sep 10, 2009, at 12:55 PM, Darin Fisher wrote: On Thu, Sep 10, 2009 at 12:32 PM, Maciej Stachowiak m...@apple.comwrote: On Sep 10, 2009, at 11:22 AM, Michael Nordman wrote: On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.org wrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.comwrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? How would the pages that failed to acquire it before know that they should try to acquire it again? Presumably they would still have to poll (assuming the tryLock model). Regards, Maciej In my proposed interace, you can wait asynchronously for the lock. Just call acquireLock with a second parameter, a closure that runs once you get the lock. What if you don't want to wait asynchronously? My reading of this is that you need two copies of the code, one that works synchronously, but you still need to keep the asynchronous model to deal with an inability to synchronously acquire the lock. What am I missing? Sounds like a problem that can be solved with a function. The reason for the trylock support is to allow a programmer to easily do nothing if they can't acquire the lock. If you want to wait if you can't acquire the lock, then using the second form of acquireLock, which takes a function, is a good solution. I don't think there is much value in the first form of acquireLock() - only the second form really makes sense. I also strongly feel that giving web developers access to locking mechanisms is a bad idea - it hasn't been a spectacular success in any other language. I think the useful semantics are equivalent to the following (being careful to avoid mentioning 'locks' or 'mutexes' explicit): A script passes in a callback and a token. The UA invokes the callback at some point in the future and provides the guarantee that no other callback with that token will be invoked in any context within the origin until the invoked callback returns. Here's what I mean with an intentionally horrible name: window.runMeExclusively(callback, arbitrary string token); This looks just like the acquireScopedLock method I proposed. An application developer could then put all of their logic that touches a particular shared resource behind a token. It's also deadlock free so long as each callback terminates. Would this be sufficient? This is sufficient for providing fine-grain locking for access to shared resources. It does not help you build long-lived locks, such as the one offline gmail constructs from using the database API and timers (see the post from michaeln). I think there are good applications for setting a long-lived lock. We can try to make it hard for people to create those locks, but then the end result will be suboptimal. They'll still find a way to build them. If so it is almost possible to implement it correctly in a JavaScript library using a shared worker per origin and postMessage, except that it is not currently possible to detect when a context goes away. Right. Maybe the answer is to add support to shared workers so that you can know when an end point disappears. Then, it would be fairly trivial to implement a lock master from a shared worker that could either manage short or long lived locks. The synchronous trylock API would not be possible, but that's fine. I only included that in my proposal for convenience. -Darin
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 2:38 PM, James Robinson jam...@google.com wrote: On Thu, Sep 10, 2009 at 1:55 PM, Darin Fisher da...@chromium.org wrote: On Thu, Sep 10, 2009 at 1:08 PM, Oliver Hunt oli...@apple.com wrote: On Sep 10, 2009, at 12:55 PM, Darin Fisher wrote: On Thu, Sep 10, 2009 at 12:32 PM, Maciej Stachowiak m...@apple.comwrote: On Sep 10, 2009, at 11:22 AM, Michael Nordman wrote: On Wed, Sep 9, 2009 at 7:55 PM, Robert O'Callahan rob...@ocallahan.org wrote: On Thu, Sep 10, 2009 at 2:38 PM, Michael Nordman micha...@google.comwrote: If this feature existed, we likely would have used it for offline Gmail to coordinate which instance of the app (page with gmail in it) should be responsible for sync'ing the local database with the mail service. In the absence of a feature like this, instead we used the local database itself to register which page was the 'syncagent'. This involved periodically updating the db by the syncagent, and periodic polling by the would be syncagents waiting to possibly take over. Much ugliness. var isSyncAgent = false; window.acquireFlag(syncAgency, function() { isSyncAgent = true; }); Much nicer. How do you deal with the user closing the syncagent while other app instances remain open? In our db polling world... that was why the syncagent periodically updated the db... to say still alive... on close it would say i'm gone and on ugly exit, the others would notice the lack of still alives and fight about who was it next. A silly bunch of complexity for something so simple. In the acquireFlag world... wouldn't the page going away simply relinquish the flag? How would the pages that failed to acquire it before know that they should try to acquire it again? Presumably they would still have to poll (assuming the tryLock model). Regards, Maciej In my proposed interace, you can wait asynchronously for the lock. Just call acquireLock with a second parameter, a closure that runs once you get the lock. What if you don't want to wait asynchronously? My reading of this is that you need two copies of the code, one that works synchronously, but you still need to keep the asynchronous model to deal with an inability to synchronously acquire the lock. What am I missing? Sounds like a problem that can be solved with a function. The reason for the trylock support is to allow a programmer to easily do nothing if they can't acquire the lock. If you want to wait if you can't acquire the lock, then using the second form of acquireLock, which takes a function, is a good solution. I don't think there is much value in the first form of acquireLock() - only the second form really makes sense. I also strongly feel that giving web developers access to locking mechanisms is a bad idea - it hasn't been a spectacular success in any other language. As proposed, its not really a locking mechanism in that nothing ever blocks. A 'flag' gets acquired by at most one context in an origin at any given time is all. Apps can make what they will out of that. I think the useful semantics are equivalent to the following (being careful to avoid mentioning 'locks' or 'mutexes' explicit): A script passes in a callback and a token. The UA invokes the callback at some point in the future and provides the guarantee that no other callback with that token will be invoked in any context within the origin until the invoked callback returns. Here's what I mean with an intentionally horrible name: window.runMeExclusively(callback, arbitrary string token); Sure, a mutex, that can be useful too. I think you can compose a 'mutex' out of the 'flag'... so in my book... the long lived 'flag' is more valuable feature. acquireFlag(mutexName, function() { do critical section stuff; releaseFlag(mutexName); } ); Now, somebody will say but what if the programmer neglects to release the flag in the event of an exceptional return. And i would say... they wrote a bug and should fix it if they wanted mutex semantics.. An application developer could then put all of their logic that touches a particular shared resource behind a token. It's also deadlock free so long as each callback terminates. Would this be sufficient? If so it is almost possible to implement it correctly in a JavaScript library using a shared worker per origin and postMessage, except that it is not currently possible to detect when a context goes away. - James -Darin
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 2:38 PM, James Robinsonjam...@google.com wrote: I also strongly feel that giving web developers access to locking mechanisms is a bad idea - it hasn't been a spectacular success in any other language. I think that you can either give web developers a strong set of concurrent-programming primitives, or you can give them a weak set and let them make up what they think they need out of those. The nice thing about providing a very basic primitives is that it's more likely that good developers can compose higher-level operations with the primitives. A few years back I proposed to some coworkers that it would be interesting to model JavaScript IPC on an existing well-formed system, such as Mach. On the surface, that sounds crazy, but once someone finds that they need to figure out how to have some code process a MessagePort in database transaction under a critical section, well, then it makes more sense to have modeled the primitives on a research project rather than be added in an ad hoc fashion. I think the useful semantics are equivalent to the following (being careful to avoid mentioning 'locks' or 'mutexes' explicit): A script passes in a callback and a token. The UA invokes the callback at some point in the future and provides the guarantee that no other callback with that token will be invoked in any context within the origin until the invoked callback returns. Here's what I mean with an intentionally horrible name: window.runMeExclusively(callback, arbitrary string token); Maybe: window.runCriticalSection(callback, identifier); -scott
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 10:46 AM, Darin Fisher da...@chromium.org wrote: On Wed, Sep 9, 2009 at 3:37 PM, Maciej Stachowiak m...@apple.com wrote: I'm really hesitant to expose explicit locking to the Web platform. Mutexes are incredibly hard to program with correctly, and we will surely end up with stuck locks, race conditions, livelocks, and so forth. For Workers I was happy that we managed to avoid any locking primitives by using a message-passing model, but explicit mutexes would ruin that. Note: I probably made a mistake calling these locks since they do not work like normal mutexes. You can only wait for one of these locks asynchronously. There is no synchronous blocking, which avoids most of the problems you mention. I don't think it does. It makes deadlock less bad, because the application can still respond to events. But there will still be deadlocks in the sense that cyclic waits-for graphs will permanently stop the application from making progress. It won't help at all with livelocks or race conditions. 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] Application defined locks
On Thu, Sep 10, 2009 at 4:59 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Fri, Sep 11, 2009 at 9:52 AM, Darin Fisher da...@chromium.org wrote: I think there are good applications for setting a long-lived lock. We can try to make it hard for people to create those locks, but then the end result will be suboptimal. They'll still find a way to build them. One use case is selecting a master instance of an app. I haven't really been following the global script thread, but doesn't that address this use case in a more direct way? No it doesn't. The global script would only be reachable by related browsing contexts (similar to how window.open w/ a name works). In a multi-process browser, you don't want to _require_ script bindings to span processes. That's why I mentioned shared workers. Because they are isolated and communication is via string passing, it is possible for processes in unrelated browsing contexts to communicate with the same shared workers. What other use-cases for long-lived locks are there? This is a good question. Most of the use cases I can imagine boil down to a master/slave division of labor. For example, if I write an app that does some batch asynchronous processing (many setTimeout calls worth), then I can imagine setting a flag across the entire job, so that other instances of my app know not to start another such overlapping job until I'm finished. In this example, I'm supposing that storage is modified at each step such that guaranteeing storage consistency within the scope of script evaluation is not enough. -Darin
Re: [whatwg] Application defined locks
On Fri, Sep 11, 2009 at 9:28 AM, Darin Fisher da...@chromium.org wrote: On Thu, Sep 10, 2009 at 4:59 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Fri, Sep 11, 2009 at 9:52 AM, Darin Fisher da...@chromium.org wrote: I think there are good applications for setting a long-lived lock. We can try to make it hard for people to create those locks, but then the end result will be suboptimal. They'll still find a way to build them. One use case is selecting a master instance of an app. I haven't really been following the global script thread, but doesn't that address this use case in a more direct way? No it doesn't. The global script would only be reachable by related browsing contexts (similar to how window.open w/ a name works). In a multi-process browser, you don't want to _require_ script bindings to span processes. That's why I mentioned shared workers. Because they are isolated and communication is via string passing, it is possible for processes in unrelated browsing contexts to communicate with the same shared workers. What other use-cases for long-lived locks are there? This is a good question. Most of the use cases I can imagine boil down to a master/slave division of labor. For example, if I write an app that does some batch asynchronous processing (many setTimeout calls worth), then I can imagine setting a flag across the entire job, so that other instances of my app know not to start another such overlapping job until I'm finished. In this example, I'm supposing that storage is modified at each step such that guaranteeing storage consistency within the scope of script evaluation is not enough. What if instead of adding locking, we added a master election mechanism? I haven't thought it out super well, but it could be something like this: You'd call some function like |window.electMaster(name, newMasterCallback, messageHandler)|. The name would allow multiple groups of master/slaves to exist. The newMasterCallback would be called any time that the master changes. It would be passed a message port if we're a slave or null if we're the master. messageHandler would be called for any messages. When we're the master, it'll be passed a message port of the slave so that responses can be sent if desired. In the gmail example: when all the windows start up, they call window.electMaster. If they're given a message port, then they'll send all messages to that master. The master would handle the request and possibly send a response. If a window is closed, then the UA will pick one of the slaves to become the master. The master would handle all the state and the slaves would be lighter weight. -- There are a couple open questions for something like this. First of all, we might want to let windows provide a hint that they'd be a bad master. For example, if they expected to be closed fairly soon. (In the gmail example, a compose mail window.) We might also want to consider allowing windows to opt out of masterhood with something like |window.yieldMasterhood()|. This would allow people to build locks upon this interface which could be good and bad. Next, we could consider adding a mechanism for the master to pickle up some amount of state and pass it on to another master. For example, maybe the |window.yieldMasterhood()| function could take a single state param that would be passed into the master via the newMasterCallback function. Lastly and most importantly, we need to decide if we think shared workers are the way all of this should be done. If so, it seems like none of this complexity is necessary. That said, until shared workers are first class citizens in terms of what APIs they can access (cookies, LocalStorage, etc), I don't think shared workers are practical for many developers and use cases.
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 6:11 PM, Jeremy Orlow jor...@chromium.org wrote: On Fri, Sep 11, 2009 at 9:28 AM, Darin Fisher da...@chromium.org wrote: On Thu, Sep 10, 2009 at 4:59 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Fri, Sep 11, 2009 at 9:52 AM, Darin Fisher da...@chromium.orgwrote: I think there are good applications for setting a long-lived lock. We can try to make it hard for people to create those locks, but then the end result will be suboptimal. They'll still find a way to build them. One use case is selecting a master instance of an app. I haven't really been following the global script thread, but doesn't that address this use case in a more direct way? No it doesn't. The global script would only be reachable by related browsing contexts (similar to how window.open w/ a name works). In a multi-process browser, you don't want to _require_ script bindings to span processes. That's why I mentioned shared workers. Because they are isolated and communication is via string passing, it is possible for processes in unrelated browsing contexts to communicate with the same shared workers. What other use-cases for long-lived locks are there? This is a good question. Most of the use cases I can imagine boil down to a master/slave division of labor. For example, if I write an app that does some batch asynchronous processing (many setTimeout calls worth), then I can imagine setting a flag across the entire job, so that other instances of my app know not to start another such overlapping job until I'm finished. In this example, I'm supposing that storage is modified at each step such that guaranteeing storage consistency within the scope of script evaluation is not enough. What if instead of adding locking, we added a master election mechanism? I haven't thought it out super well, but it could be something like this: You'd call some function like |window.electMaster(name, newMasterCallback, messageHandler)|. The name would allow multiple groups of master/slaves to exist. The newMasterCallback would be called any time that the master changes. It would be passed a message port if we're a slave or null if we're the master. messageHandler would be called for any messages. When we're the master, it'll be passed a message port of the slave so that responses can be sent if desired. In the gmail example: when all the windows start up, they call window.electMaster. If they're given a message port, then they'll send all messages to that master. The master would handle the request and possibly send a response. If a window is closed, then the UA will pick one of the slaves to become the master. The master would handle all the state and the slaves would be lighter weight. -- There are a couple open questions for something like this. First of all, we might want to let windows provide a hint that they'd be a bad master. For example, if they expected to be closed fairly soon. (In the gmail example, a compose mail window.) We might also want to consider allowing windows to opt out of masterhood with something like |window.yieldMasterhood()|. This would allow people to build locks upon this interface which could be good and bad. Next, we could consider adding a mechanism for the master to pickle up some amount of state and pass it on to another master. For example, maybe the |window.yieldMasterhood()| function could take a single state param that would be passed into the master via the newMasterCallback function. Lastly and most importantly, we need to decide if we think shared workers are the way all of this should be done. If so, it seems like none of this complexity is necessary. That said, until shared workers are first class citizens in terms of what APIs they can access (cookies, LocalStorage, etc), I don't think shared workers are practical for many developers and use cases. What about eliminating shared memory (only one context would be allowed access to cookies, localStorage, etc)? It seems to be working out fine for DOM access and is much, much easier to reason about. - James
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 5:28 PM, Darin Fisher da...@chromium.org wrote: On Thu, Sep 10, 2009 at 4:59 PM, Robert O'Callahan rob...@ocallahan.orgwrote: On Fri, Sep 11, 2009 at 9:52 AM, Darin Fisher da...@chromium.org wrote: I think there are good applications for setting a long-lived lock. We can try to make it hard for people to create those locks, but then the end result will be suboptimal. They'll still find a way to build them. One use case is selecting a master instance of an app. I haven't really been following the global script thread, but doesn't that address this use case in a more direct way? No it doesn't. The global script would only be reachable by related browsing contexts (similar to how window.open w/ a name works). In a multi-process browser, you don't want to _require_ script bindings to span processes. That's why I mentioned shared workers. Because they are isolated and communication is via string passing, it is possible for processes in unrelated browsing contexts to communicate with the same shared workers. What other use-cases for long-lived locks are there? This is a good question. Most of the use cases I can imagine boil down to a master/slave division of labor. For example, if I write an app that does some batch asynchronous processing (many setTimeout calls worth), then I can imagine setting a flag across the entire job, so that other instances of my app know not to start another such overlapping job until I'm finished. In this example, I'm supposing that storage is modified at each step such that guaranteeing storage consistency within the scope of script evaluation is not enough. -Darin Also, the other motivating factor for me is access to LocalStorage from workers. (I know it has been removed from the spec, but that is unfortunate, no?) By definition, workers are designed to be long lived, possibly doing long stretches of computation, and being able to intermix reads and writes to storage during that stretch of computation would be nice. Moreover, it would be nice if a worker in domain A could effectively lock part of the storage so that the portion of the app running on the main thread could continue accessing the other parts of storage associated with domain A. The implicit storage mutex doesn't support this use case very well. You end up having to call the getStorageUpdates function periodically (releasing the lock in the middle of computation!!). That kind of thing is really scary and hard to get right. I cringe whenever I see someone unlocking, calling out to foreign code, and then re-acquiring the lock. Why? because it means that existing variables, stack based or otherwise, that were previously consistent may have become inconsistent with global data in storage due to having released the lock. getStorageUpdates is dangerous. it is a big hammer that doesn't really fit the bill. The alternative to getStorageUpdates in this case is to create another domain on which to run the background worker just so that you can have an independent slice of storage. That seems really lame to me. Why should domain A have to jump through such hoops? -Darin
Re: [whatwg] Application defined locks
On Thu, Sep 10, 2009 at 7:59 PM, Darin Fisher da...@chromium.org wrote: rt oOn Thu, Sep 10, 2009 at 6:35 PM, James Robinson jam...@google.comwrote: On Thu, Sep 10, 2009 at 6:11 PM, Jeremy Orlow jor...@chromium.orgwrote: On Fri, Sep 11, 2009 at 9:28 AM, Darin Fisher da...@chromium.orgwrote: On Thu, Sep 10, 2009 at 4:59 PM, Robert O'Callahan rob...@ocallahan.org wrote: On Fri, Sep 11, 2009 at 9:52 AM, Darin Fisher da...@chromium.orgwrote: I think there are good applications for setting a long-lived lock. We can try to make it hard for people to create those locks, but then the end result will be suboptimal. They'll still find a way to build them. One use case is selecting a master instance of an app. I haven't really been following the global script thread, but doesn't that address this use case in a more direct way? No it doesn't. The global script would only be reachable by related browsing contexts (similar to how window.open w/ a name works). In a multi-process browser, you don't want to _require_ script bindings to span processes. That's why I mentioned shared workers. Because they are isolated and communication is via string passing, it is possible for processes in unrelated browsing contexts to communicate with the same shared workers. What other use-cases for long-lived locks are there? This is a good question. Most of the use cases I can imagine boil down to a master/slave division of labor. For example, if I write an app that does some batch asynchronous processing (many setTimeout calls worth), then I can imagine setting a flag across the entire job, so that other instances of my app know not to start another such overlapping job until I'm finished. In this example, I'm supposing that storage is modified at each step such that guaranteeing storage consistency within the scope of script evaluation is not enough. What if instead of adding locking, we added a master election mechanism? I haven't thought it out super well, but it could be something like this: You'd call some function like |window.electMaster(name, newMasterCallback, messageHandler)|. The name would allow multiple groups of master/slaves to exist. The newMasterCallback would be called any time that the master changes. It would be passed a message port if we're a slave or null if we're the master. messageHandler would be called for any messages. When we're the master, it'll be passed a message port of the slave so that responses can be sent if desired. In the gmail example: when all the windows start up, they call window.electMaster. If they're given a message port, then they'll send all messages to that master. The master would handle the request and possibly send a response. If a window is closed, then the UA will pick one of the slaves to become the master. The master would handle all the state and the slaves would be lighter weight. -- There are a couple open questions for something like this. First of all, we might want to let windows provide a hint that they'd be a bad master. For example, if they expected to be closed fairly soon. (In the gmail example, a compose mail window.) We might also want to consider allowing windows to opt out of masterhood with something like |window.yieldMasterhood()|. This would allow people to build locks upon this interface which could be good and bad. Next, we could consider adding a mechanism for the master to pickle up some amount of state and pass it on to another master. For example, maybe the |window.yieldMasterhood()| function could take a single state param that would be passed into the master via the newMasterCallback function. Lastly and most importantly, we need to decide if we think shared workers are the way all of this should be done. If so, it seems like none of this complexity is necessary. That said, until shared workers are first class citizens in terms of what APIs they can access (cookies, LocalStorage, etc), I don't think shared workers are practical for many developers and use cases. What about eliminating shared memory (only one context would be allowed access to cookies, localStorage, etc)? It seems to be working out fine for DOM access and is much, much easier to reason about. - James It is a good idea. If we were to start fresh, it'd probably be the ideal answer. We could say that each SharedWorker gets its own slice of persistent storage independent from the rest. But this ship has sailed for cookies at least, document.cookies is problematic but considering the many other issues with this API it's probably not going to be the end of the world to have it be a touch pricklier. and database and localstorage are already shipping in UAs. Is it really too late for DB and localStorage? I'm still trying to get used to the standards process used here but I thought the idea with UAs implementing draft specs is that the feedback