- From: Israel Hilerio <israelh@microsoft.com>
- Date: Fri, 15 Jul 2011 00:27:25 +0000
- To: "Jonas Sicking (jonas@sicking.cc)" <jonas@sicking.cc>
- CC: "public-webapps@w3.org" <public-webapps@w3.org>, David Sheldon <dsheldon@microsoft.com>
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