RE: RE: [IndexedDB] Client API state after calling deleteIndex and deleteObjectStore

On Thursday, July 14, 2011 1:57 PM, Jonas Sicking wrote:
> On Thu, Jul 14, 2011 at 1:20 PM, Israel Hilerio <israelh@microsoft.com> wrote:
> > On Wednesday, July 13, 2011 2:02 PM, Jonas Sicking wrote:
> >> On Wed, Jul 13, 2011 at 11:39 AM, Israel Hilerio
> >> <israelh@microsoft.com>
> >> wrote:
> >> > What should be the client state after a deleteIndex is called?
> >> > For example looking at the code below:
> >> >
> >> > 1. var index = objStore.index(indexName); 2.
> >> > objStore.deleteIndex(indexName); 3. try { 4.
> >> > index.openCursor().onerror = function (e) { log("failed to open
> >> > cursor"); } 5. } catch (ex) { 6.      log ("failed to call
> >> > openCursor"); 7. }
> >> >
> >> > Similar to our previous conversation around transaction.abort, it
> >> > seems that
> >> we would want to keep some knowledge on the client that the index was
> >> deleted at line #2 and therefore, line #4 will throw an exception
> >> that will be handled by line #6.  In this case, the onerror handler
> >> at line #4 will never be executed.
> >> >
> >> > Do you agree?
> >>
> >> Yes! I do think we need to modify the spec to specify this.
> >>
> >> > Would it be good enough to just throw an UNKNOWN_ERR or we could
> >> create a new error code for this (e.g. CALLER_ERR or OBJECT_ERR).
> >>
> >> I would say NOT_ALLOWED_ERR or NOT_FOUND_ERR would be ok for this
> >> case.
> >>
> >> > Also, what should happen to deleteObjectStore when it is called in
> >> > a similar
> >> situation:
> >> >
> >> > 1. var objStore = db.createObjectStore(osName, {keyPath: "name"}); 2.
> >> > db.deleteObjectStore(osName); 3. try { 4.
> >> > objStore.index(indexName); 5. } catch (ex) { 6.     Log ("failed to
> >> > call index"); 7. }
> >> >
> >> > I would also expect us to keep knowledge on the client that the
> >> > objStore
> >> was deleted at line #2 and therefore not allow line #4 from queuing
> >> up a request but fail fast with an exception.  We could throw the
> >> same exception as the example above.
> >> >
> >> > Do you agree?
> >>
> >> Yup. Seems identical to the situation you described above.
> >>
> >> By the way, I assume this is only relevant during VERSION_CHANGE
> >> transactions, right?
> >>
> >> Another tricky situation is what to do with code like
> >>
> >> 1. var index = objStore.index(indexName); 2. req = index.get(2); 3.
> >> req.onsuccess = function() { log("didn't fail, value is" + req.result) }; 4.
> >> req.onerror = function() { log("error was fired") }; 5.
> >> objStore.deleteIndex(indexName);
> >>
> >> I don't feel strongly what should happen. From an implementation
> >> point of view it might be easy either way. In fact I think in the
> >> Gecko implementation it might be easier to the request succeed and
> >> deliver the same data as if the index hadn't been deleted, than to
> >> let it fail. This is because all requests run on the same database
> >> thread (in order to ensure that they run in the proper order), and so
> >> by the time the index is deleted, we have already read data out from it.
> >>
> >> From a user point of view it might be slightly more useful if the
> >> request succeeds, but it also seems quite ok to require that people
> >> don't delete an index or objectStore unless they don't expect to get more
> data from it.
> >>
> >> / Jonas
> >
> > We agree with you that we should let the previously queued up operations
> finish before the deleteIndex or deleteObjectStore impacts them.  However,
> after the deleteIndex or deleteObjectStore are executed in the client, we
> don't want to allow further calls to be invoked on these objects.  We want to
> immediately throw an exception (NOT_ALLOWED_ERR).  This implies that the
> client APIs don't have to wait for the deleteIndex and deleteObjecStore to be
> processed by the server and that the source objects will keep some type of
> information about their deleted state.  It seems a waist of cycles, to allow
> these operations to be queued on the server to find out that the source
> objects don't exists any more.
> >
> > We believe this simplifies the programming model and makes it more
> deterministic.
> >
> > What do you think?
> 
> It sounds like we agree!
> 
> To make sure we're on the same page, here's pulling all the examples
> together.
> 
> 
> 1. var index = objStore.index(indexName); 2.
> objStore.deleteIndex(indexName); 3. try {
> 4.       index.openCursor().onerror = function (e) { log("failed to
> open cursor"); }
> 5. } catch (ex) {
> 6.      log ("failed to call openCursor");
> 7. }
> 
> Here the openCursor call on line 4 should throw, causing the call on line 6 to
> execute next. The onerror assignment never happens as the exception is
> thrown before that, and thus the log call on line 4 is never called.
> 
> 
> 1. var objStore = db.createObjectStore(osName, {keyPath: "name"}); 2.
> db.deleteObjectStore(osName); 3. try {
> 4.     objStore.index(indexName);
> 5. } catch (ex) {
> 6.     log("failed to call index");
> 7. }
> 
> Here the index call on line 4 should throw, causing the call on line 6 to
> execute next.
> 
> 
> 1. var index = objStore.index(indexName); 2. req = index.get(2); 3.
> req.onsuccess = function() { log("didn't fail, value is" + req.result) }; 4.
> req.onerror = function() { log("error was fired") }; 5.
> objStore.deleteIndex(indexName); 6. db.deleteObjectStore(objStore.name);
> 
> Here the function assigned to the onsuccess property on line 3 will eventually
> be called and will log whatever value is stored for in the index at key 2 (or if
> no such value was stored, it'll log <undefiend>). The function assigned to the
> onerror handler on line 4 is never called.
> 
> The same thing would happen if line 5 was removed as removing an
> objectStore also removes all its indexes.
> 
> 
> Another even more complex scenario not brought up yet:
> 
> 1. var index = objStore.index(indexName); 2. req = index.openCursor(); 3.
> req.onsuccess = function() { var curs = res.result; if (curs) { log("found value " +
> curs.value); curs.continue(); } }; 4. req.onerror = function() { log("error was
> fired") }; 5. objStore.deleteIndex(indexName);
> 
> In this scenario the function assigned to the onsuccess property on line 3 is
> called once and will log the first value in the index.
> However when that function calls curs.continue, the call to continue will
> throw an exception as the index has been deleted.
> 
> Hence the onsuccess function will only be called once, and the onerror
> function won't be called at all.
> 
> 
> Does this match your understanding?
> 
> / Jonas

Thanks for putting the last example together.
Yes, this matches our understanding.

Israel

Received on Friday, 15 July 2011 00:27:56 UTC