Re: InedxedDB events : misconception?
Oh, sorry... and thank you all for your explanations. :)
Re: InedxedDB events : misconception?
Ok, the example of console.log () has made me realize something I had never seen that. In short, if I understood from my tests, asynchronous instruction is executed at the earliest, after the last statement of the scope in which it is declared. There was a misconception ... in my mind. Please apologize for the inconvenience. Cordially, Michaël
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 12:32 PM, Alec Flett wrote: > On Mon, Apr 22, 2013 at 9:56 AM, Michaël Rouges > wrote: > >> >> Hum ... thank you for this answer, but ... >> >> Are you sure there is no possibility that the application is completed >> before adding events? >> >> I find it hard to perceive how it couldn't happen. >> > > Just to close the loop on this concern: the reason there is no possibility > is that this part of the IndexedDB specification - all browsers must > guarantee this behavior to have a working IndexedDB - in fact the rest of > IndexedDB itself would be unusable if this guarantee was not met. > > Stuff like this can feel a little awkward if you're using to dealing in a > multi-threaded world, but this API is fairly normal for a web api, at least > in this respect. In fact XHR is the outlier here in requiring a specific > xhrrequest.send() call. > > Yeah, there's a bunch of APIs like this; EventSource, Notification, IndexDB's stuff, ... - E
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 1:57 PM, Kyle Huey wrote: > On Mon, Apr 22, 2013 at 1:50 PM, Joshua Bell wrote: > >> FWIW, we had a Chrome IDB bug report where someone used the developer >> tools to set a script breakpoint between the open() call and the event >> handler assignments. The debugger spins the event loop, so the event was >> dispatched before the handlers were assigned. The answer was "so don't do >> that", but it's a similar API/platform gotcha leading to developer >> confusion. >> > > I would claim that's an implementation bug > Agreed, and apologies for implying I felt otherwise otherwise. To clarify: "don't do that until the debugger architecture is changed". (Also, apologies if you get this more or less than one time. I'm trying to switch my mailing list subscription over to my @google.com account but hitting a list server problem.)
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 1:50 PM, Joshua Bell wrote: > FWIW, we had a Chrome IDB bug report where someone used the developer > tools to set a script breakpoint between the open() call and the event > handler assignments. The debugger spins the event loop, so the event was > dispatched before the handlers were assigned. The answer was "so don't do > that", but it's a similar API/platform gotcha leading to developer > confusion. > I would claim that's an implementation bug. - Kyle
Re: InedxedDB events : misconception?
Resending from the correct account: FWIW, we had a Chrome IDB bug report where someone used the developer tools to set a script breakpoint between the open() call and the event handler assignments. The debugger spins the event loop, so the event was dispatched before the handlers were assigned. The answer was "so don't do that", but it's a similar API/platform gotcha leading to developer confusion. On Mon, Apr 22, 2013 at 10:36 AM, Boris Zbarsky wrote: > On 4/22/13 1:31 PM, Tab Atkins Jr. wrote: > >> Is there a reason to not pass the success/error/upgradeneeded callbacks >>> in a >>> dictionary to open() in this case, so that the request object is born >>> with >>> the right bits and the actual reques it not kicked off until _after_ the >>> side-effects of getting them off the dictionary have fully run to >>> completion? >>> >> >> Dunno, ask sicking. But events do have some benefits over passed >> callbacks. >> > > I don't understand the distinction. > > My straw-man proposal here is just that there is a dictionary with the > three callbacks and then the return value has its > onsuccess/onerror/**onupgradeneeded > set to those three callbacks before the actual request is kicked off and > the request object is returned. > > > (The right answer is to figure out some way to accommodate IDB's >> locking semantics in a future. sicking and annevk have some >> discussion on this. Then there's no possibility of event races, >> because your callback will still be fired even if you lose the race.) >> > > That would be good, yes. > > > Given the "upgradeneeded" mechanism, it might end up being a hybrid of passed-callbacks and futures, e.g. futureSavvyIndexedDB.open(name, ver, { upgradeneeded: function(db) { /* upgrade logic */ } ).then( function(db) { /* success */ }, function(err) { /* failure */ } ); ... with "blocked" events wedged in there somehow as future progress notifications or some such. (I haven't followed the latest on that.) > Synchronously spinning the event loop is the devil. :/ >> > > Well, yes. ;) > > -Boris > > >
Re: InedxedDB events : misconception?
On 4/22/13 4:36 PM, Joshua Bell wrote: The debugger spins the event loop Fwiw, that seems like a bug in the debugger (albeit a common one in browser debuggers) :( -Boris
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 9:56 AM, Michaël Rouges wrote: > > Hum ... thank you for this answer, but ... > > Are you sure there is no possibility that the application is completed > before adding events? > > I find it hard to perceive how it couldn't happen. > Just to close the loop on this concern: the reason there is no possibility is that this part of the IndexedDB specification - all browsers must guarantee this behavior to have a working IndexedDB - in fact the rest of IndexedDB itself would be unusable if this guarantee was not met. Stuff like this can feel a little awkward if you're using to dealing in a multi-threaded world, but this API is fairly normal for a web api, at least in this respect. In fact XHR is the outlier here in requiring a specific xhrrequest.send() call. Alec
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 9:56 AM, Michaël Rouges wrote: > > Hum ... thank you for this answer, but ... > > Are you sure there is no possibility that the application is completed > before adding events? > > I find it hard to perceive how it couldn't happen. Do you also worry that if you wrote: x = 0; setTimeout(function() { x = 1; }, 0); console.log(x); console.log(x); console.log(x); console.log(x); console.log(x); console.log(x); that there's a risk that you'd get a few 0's in the log, but at some point it would switch to logging 1's? No developer that I've talked to think that that could happen in JS. And it can't. It's clear to everyone that you'll only get 0's. The reason is that JS is single threaded and the setTimeout callback is run asynchronously. It's the same thing in IDB. The .onsuccess property is triggered asynchronously which means that it couldn't happen in the middle of your execution. / Jonas
Re: InedxedDB events : misconception?
On 4/22/13 1:41 PM, Tab Atkins Jr. wrote: On Mon, Apr 22, 2013 at 10:36 AM, Boris Zbarsky wrote: On 4/22/13 1:31 PM, Tab Atkins Jr. wrote: Is there a reason to not pass the success/error/upgradeneeded callbacks in a dictionary to open() in this case, so that the request object is born with the right bits and the actual reques it not kicked off until _after_ the side-effects of getting them off the dictionary have fully run to completion? Dunno, ask sicking. But events do have some benefits over passed callbacks. I don't understand the distinction. Callback arguments can only be "registered" once. Events can be listened to multiple times. What I meant is that I don't understand the distinction between the two in this particular case, when I am proposing that the callback arguments be registered as event listeners by the call. I understand the general difference between the two, thanks. ;) This does mean that if you have more than one success listener you lose, of course -Boris
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 10:36 AM, Boris Zbarsky wrote: > On 4/22/13 1:31 PM, Tab Atkins Jr. wrote: >>> Is there a reason to not pass the success/error/upgradeneeded callbacks >>> in a >>> dictionary to open() in this case, so that the request object is born >>> with >>> the right bits and the actual reques it not kicked off until _after_ the >>> side-effects of getting them off the dictionary have fully run to >>> completion? >> >> Dunno, ask sicking. But events do have some benefits over passed >> callbacks. > > I don't understand the distinction. Callback arguments can only be "registered" once. Events can be listened to multiple times. Whether or not that distinction is useful here can be debated, but it's a salient difference. ~TJ
Re: InedxedDB events : misconception?
On 4/22/13 1:31 PM, Tab Atkins Jr. wrote: Is there a reason to not pass the success/error/upgradeneeded callbacks in a dictionary to open() in this case, so that the request object is born with the right bits and the actual reques it not kicked off until _after_ the side-effects of getting them off the dictionary have fully run to completion? Dunno, ask sicking. But events do have some benefits over passed callbacks. I don't understand the distinction. My straw-man proposal here is just that there is a dictionary with the three callbacks and then the return value has its onsuccess/onerror/onupgradeneeded set to those three callbacks before the actual request is kicked off and the request object is returned. (The right answer is to figure out some way to accommodate IDB's locking semantics in a future. sicking and annevk have some discussion on this. Then there's no possibility of event races, because your callback will still be fired even if you lose the race.) That would be good, yes. Synchronously spinning the event loop is the devil. :/ Well, yes. ;) -Boris
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 10:17 AM, Boris Zbarsky wrote: > On 4/22/13 12:47 PM, Tab Atkins Jr. wrote: >> As long as you don't spin the event loop > > That's tricky. Here's some simple code at global scope: > > > request = indexedDB.open('database'); > request.onsuccess = function () {}; > > Can that code spin the event loop between the open() call and the onsuccess > setter being invoked? > > Sure: all it takes is someone defining a setter for "request" on the window > that just saves the given value and a getter for "request" that calls > showModalDialog to ask the user whether to allow the get and then returns > the saved value. > > Now why someone would do that, I have no idea, but that's true for a lot of > things people do in practice in websites. ;) My point is that whether the > event loop spins is a very non-local property of the code. It's annoying to > have to depend on such things. > > Is there a reason to not pass the success/error/upgradeneeded callbacks in a > dictionary to open() in this case, so that the request object is born with > the right bits and the actual reques it not kicked off until _after_ the > side-effects of getting them off the dictionary have fully run to > completion? Dunno, ask sicking. But events do have some benefits over passed callbacks. (The right answer is to figure out some way to accommodate IDB's locking semantics in a future. sicking and annevk have some discussion on this. Then there's no possibility of event races, because your callback will still be fired even if you lose the race.) >> This... is precisely the sort of thing that you shouldn't do. Just >> don't do this, and you're golden. > > I don't believe you are; see above. > > >> The "request.execute()" is more or less implied by hitting the bottom >> of your function, when it returns control back to the browsers. > > We wish; see above. Synchronously spinning the event loop is the devil. :/ ~TJ
Re: InedxedDB events : misconception?
Sorry, I usually speak french and my english is quite experimental. The example I gave, with SetTimeout() is useless, if not illustrate that the interpreter does not expect that the events are attached to execute the query. My surprise comes from the comparison with the XMLHttpRequest object, which is usually added events before executing the query. This behavior (XMLHttpRequest) seems more natural to me. It creates the object and its properties and only then starts the execution may require these properties. As it happens, with IndexedDB objects, we can only hope that the events are attached before, by the interpreter.
Re: InedxedDB events : misconception?
On 4/22/13 12:47 PM, Tab Atkins Jr. wrote: As long as you don't spin the event loop That's tricky. Here's some simple code at global scope: request = indexedDB.open('database'); request.onsuccess = function () {}; Can that code spin the event loop between the open() call and the onsuccess setter being invoked? Sure: all it takes is someone defining a setter for "request" on the window that just saves the given value and a getter for "request" that calls showModalDialog to ask the user whether to allow the get and then returns the saved value. Now why someone would do that, I have no idea, but that's true for a lot of things people do in practice in websites. ;) My point is that whether the event loop spins is a very non-local property of the code. It's annoying to have to depend on such things. Is there a reason to not pass the success/error/upgradeneeded callbacks in a dictionary to open() in this case, so that the request object is born with the right bits and the actual reques it not kicked off until _after_ the side-effects of getting them off the dictionary have fully run to completion? This... is precisely the sort of thing that you shouldn't do. Just don't do this, and you're golden. I don't believe you are; see above. The "request.execute()" is more or less implied by hitting the bottom of your function, when it returns control back to the browsers. We wish; see above. -Boris
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 9:56 AM, Michaël Rouges wrote: > Hum ... thank you for this answer, but ... > > Are you sure there is no possibility that the application is completed > before adding events? > > I find it hard to perceive how it couldn't happen. I don't quite understand what you're asking. Are you asking if I'm sure that events will never be sent before the end of your function? Yes, I'm sure of this - it's part of Javascript's core semantics. As long as you register your callbacks before you yield control back to the browser, there is absolutely no chance of you missing any events. ~TJ
Re: InedxedDB events : misconception?
Hum ... thank you for this answer, but ... Are you sure there is no possibility that the application is completed before adding events? I find it hard to perceive how it couldn't happen.
Re: InedxedDB events : misconception?
On Mon, Apr 22, 2013 at 9:43 AM, Michaël Rouges wrote: > Hello everyone, > > I'm surprised by how events are added to IndexedDB objects. > > For example, base, opening a database: > > var request; > request = indexedDB.open('database'); > request.onsuccess = function () {}; > request.onupgradeneeded = function () {}; > request.onerror = function () {}; > > As you can see, the events are added after the query execution. > > It does not seem natural and can cause stability problems. > > Indeed, if the application had to be completed by the addition of events, > they will never be triggered. Events don't fire until the next tick. As long as you don't spin the event loop, there's no race conditions and everything's fine. > Here is an example generates an error: > > var request; > request = indexedDB.open('database'); > setTimeout(function () { > request.onsuccess = function () {}; > request.onupgradeneeded = function () {}; > request.onerror = function () {}; > }, 1500); This... is precisely the sort of thing that you shouldn't do. Just don't do this, and you're golden. > In my view, any item requiring events should be set first, then we add the > events and finally, we execute it. > > The code should look like this: > > var request; > request = indexedDB.open('database'); > request.onsuccess = function () {}; > request.onupgradeneeded = function () {}; > request.onerror = function () {}; > request.execute(); The "request.execute()" is more or less implied by hitting the bottom of your function, when it returns control back to the browsers. ~TJ
InedxedDB events : misconception?
Hello everyone, I'm surprised by how events are added to IndexedDB objects. For example, base, opening a database: var request; request = indexedDB.open('database'); request.onsuccess = function () {}; request.onupgradeneeded = function () {}; request.onerror = function () {}; As you can see, the events are added after the query execution. It does not seem natural and can cause stability problems. Indeed, if the application had to be completed by the addition of events, they will never be triggered. Here is an example generates an error: var request; request = indexedDB.open('database'); setTimeout(function () { request.onsuccess = function () {}; request.onupgradeneeded = function () {}; request.onerror = function () {}; }, 1500); In my view, any item requiring events should be set first, then we add the events and finally, we execute it. The code should look like this: var request; request = indexedDB.open('database'); request.onsuccess = function () {}; request.onupgradeneeded = function () {}; request.onerror = function () {}; request.execute(); For additional information and / or feedback, do not hesitate to contact me. ;)