W3C home > Mailing lists > Public > public-webapps@w3.org > July to September 2010

Re: [IndexedDB] Re: onsuccess callback in race condition?

From: <victor.hong@nokia.com>
Date: Thu, 15 Jul 2010 21:16:56 +0200
To: <jorlow@chromium.org>
CC: <public-webapps@w3.org>
Message-ID: <C864D6E8.D7E9%victor.hong@nokia.com>



On 7/15/10 1:13 PM, "ext Jeremy Orlow" <jorlow@chromium.org> wrote:

> On Thu, Jul 15, 2010 at 6:04 PM,  <victor.hong@nokia.com> wrote:
>> 
>> Hi Jeremy,
>> 
>> Thank you for responding. If I understand you correctly, the example 1 could
>> produce a race condition,
> 
> I don't see how.  onsuccess is always set immediately after the request object
> is created by the asynchronous call.
>  
>> and example 2 will not.
> 
> This example is completely outdated and will not work period.  Please take a
> look at the latest editors draft.  (A lot of the async changes were just
> committed.)
>  

I was quoting from this draft (July 15 2010)
http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html

Is it outdated already?
And where do I go for the latest?

>> However, example 2 will assume that request object is a member of IndexDB,
>> which seems not in the interface for the time being:
>> interface IDBFactory {
>>>>     readonly attribute DOMStringList databases;
>>>>     IDBRequest open (in DOMString name, in DOMString description) raises
>>>> (IDBDatabaseException);
>>>> };
>> Should request be part of every indexedDB object?
>> 
>> Regarding to allowing someone to set an onsuccess/onerror handler after the
>> event has fired, I think that it¹s very convenient.
> 
> Are you saying _not_ allowing it is convenient?  I'm going to assume so
> because there's really no use case for why one would want to set them after
> they would have fired.

I am saying that allowing setting handler after event has been fired is
convenient. But I agree that the use case might be rare if there is no race
condition here.


>  
>> One possible idea, is to offer an addCallback function in request object. So
>> it will be like;
>> 
>> var request = IndexedDB.open();
>> request.addOnSuccessCallback(mySuccessCallback);
>> request.addOnErrorCallback(myErrorCallback);
>> 
>> The addOnSuccessCallback call will
>> 1. make assignment request.onsuccess =  mySuccessCallback;
>> 2. check the ready state, if the open() call has been fired, and completed,
>> then call mySuccessCallback(event) immediately with event object
>> 
>> Could this work?
> 
> Well, most of this is already done since IDBRequest is an event target, so you
> can do .addEventListener.  As for firing afterwards, I don't believe there's
> any precident in any other event listener.  And I can't think of too many
> cases where you'd really need to set the event handler after doing some other
> asynchronous action, so I don't think it's worth creating our own custom
> behavior for this case.
>  
>> 
>> If we take this approach, the request object does not need to be part of
>> IndexedDB object. It will be returned from indexedDB.open() then callbacks
>> can be added to it, without worrying about race condition.
> 
> There aren't race conditions currently.  You just need to set it before you
> return control to the browser.
>  
>> 
>> Victor
>> 
>> 
>> On 7/15/10 12:14 PM, "ext Jeremy Orlow" <jorlow@chromium.org
>> <http://jorlow@chromium.org> > wrote:
>> 
>>> First of all, any chance you could prefix IndexedDB discussions with
>>> [IndexedDB] in the subject so that people have the option to filter them if
>>> they wish?
>>> 
>>> To answer your question:  The intention is that onsuccess is not inspected
>>> until the event would fire.  And the event would not fire until after you
>>> return from your currently running JavaScript.  But if you did do something
>>> asynchornous and then set it after that, it would be a race.  But you could
>>> look at the ready state to see whether you've missed the boat or not.
>>> 
>>> This does bring up an interesting question.  Should we allow someone to set
>>> an onsuccess/onerror handler after the event has fired?  Afte rall, we know
>>> there's no chance of it ever firing.
>>> 
>>> Also, I wonder if we should try to add some text to make this more clear in
>>> the spec.
>>> 
>>> J
>>> 
>>> On Thu, Jul 15, 2010 at 4:13 PM,  <victor.hong@nokia.com
>>> <http://victor.hong@nokia.com> > wrote:
>>>> Hi,
>>>> 
>>>> I would like to get some clarification on async implementation of the
>>>> indexedDB API.
>>>> 
>>>> Example 1:
>>>> Below is a sample code from the following blog article.
>>>> http://hacks.mozilla.org/2010/06/comparing-indexeddb-and-webdatabase/
>>>> 
>>>> var request = window.indexedDB.open("CandyDB",
>>>>                                     "My candy store database");
>>>> request.onsuccess = function(event) {
>>>>   var db = event.result;
>>>>   if (db.version != "1") {
>>>>     // User's first visit, initialize database.
>>>>     var createdObjectStoreCount = 0;
>>>>     var objectStores = [
>>>>       { name: "kids", keyPath: "id", autoIncrement: true },
>>>>       { name: "candy", keyPath: "id", autoIncrement: true },
>>>>       { name: "candySales", keyPath: "", autoIncrement: true }
>>>>     ];
>>>> 
>>>>     function objectStoreCreated(event) {
>>>>       if (++createdObjectStoreCount == objectStores.length) {
>>>>         db.setVersion("1").onsuccess = function(event) {
>>>>           loadData(db);
>>>>         };
>>>>       }
>>>>     }
>>>> 
>>>>     for (var index = 0; index < objectStores.length; index++) {
>>>>       var params = objectStores[index];
>>>>       request = db.createObjectStore(params.name <http://params.name>
>>>> <http://params.name> , params.keyPath,
>>>> 
>>>>                                      params.autoIncrement);
>>>>       request.onsuccess = objectStoreCreated;
>>>>     }
>>>>   }
>>>>   else {
>>>>     // User has been here before, no initialization required.
>>>>     loadData(db);
>>>>   }
>>>> };
>>>> 
>>>> In this code, request is returned from request = window.indexedDB.open()
>>>> call, then request.onsuccess = function() {...} is assigned.
>>>> 
>>>> Maybe I don't fully understand how this IndexedDB works,
>>>> it seems that there could be a race condition between the open() operation
>>>> and request.onsuccess assignment. The open() operation could be completed
>>>> before request.onsuccess got assigned to a callback function. Does this
>>>> mean
>>>> that the request.onsuccess callback function will not be called?
>>>> 
>>>> Is there a mechanism to assure that the callback gets called regardless
>>>> whether the open() operation completed or not when request.onsuccess is
>>>> assigned to a callback function?
>>>> 
>>>> Of course, the same issue exists for all other async calls.
>>>> 
>>>> Whether this can be assured or not, maybe the spec document can point it
>>>> out
>>>> if not already in the coming draft.
>>>> 
>>>> Example 2:
>>>> On the other hand, in the July 15, 2010 editor's draft, 3.2.2 The
>>>> IDBRequest
>>>> Interface section, there is an example:
>>>> 
>>>> indexedDB.request.onsuccess = function(evt) {...};
>>>> indexedDB.request.onerror = function(evt) {...};
>>>> indexedDB.open('AddressBook', 'Address Book');
>>>> 
>>>> This indicates that request object is a member of indexedDB interface, and
>>>> request.onsuccess can be assigned to a callback before indexDB.open() is
>>>> called, therefore is no race condition issue here.
>>>> 
>>>> But IndexDB is a
>>>> interface IDBFactory {
>>>>     readonly attribute DOMStringList databases;
>>>>     IDBRequest open (in DOMString name, in DOMString description) raises
>>>> (IDBDatabaseException);
>>>> };
>>>> 
>>>> It does not appear to have a request object as member.
>>>> 
>>>> 
>>>> Can someone clarify these above 2 examples for me?
>>>> 
>>>> Does request.onsuccess need to be assigned to a callback before
>>>> indexDB.open() get called to avoid race condition? Like in example 2)
>>>> 
>>>> Maybe both examples are correct. Then what makes sure that in example 1)
>>>> the
>>>> callback function get called even if open() has been completed before the
>>>> callback function is assigned to request.onsuccess?
>>>> 
>>>> Thank you.
>>>> Victor
>>>> 
>>>> 
>>>> 
>>> 
>>> 
> 
> 
Received on Thursday, 15 July 2010 19:17:47 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:39 GMT