WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
92674
IndexedDB: Layout test showing delete database getting two blocked events
https://bugs.webkit.org/show_bug.cgi?id=92674
Summary
IndexedDB: Layout test showing delete database getting two blocked events
David Grogan
Reported
2012-07-30 13:30:34 PDT
Layout test showing delete database getting two receive events
Attachments
Patch
(5.65 KB, patch)
2012-07-30 13:31 PDT
,
David Grogan
no flags
Details
Formatted Diff
Diff
Patch
(5.63 KB, patch)
2012-07-30 13:39 PDT
,
David Grogan
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from gce-cr-linux-05
(358.43 KB, application/zip)
2012-07-30 14:19 PDT
,
WebKit Review Bot
no flags
Details
Patch
(27.29 KB, patch)
2012-08-16 16:30 PDT
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(52.61 KB, patch)
2012-08-23 16:07 PDT
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(30.27 KB, patch)
2012-08-24 12:39 PDT
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from gce-cr-linux-07
(341.25 KB, application/zip)
2012-08-24 14:39 PDT
,
WebKit Review Bot
no flags
Details
Patch
(22.10 KB, patch)
2012-12-18 15:46 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(29.06 KB, patch)
2012-12-19 15:20 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Show Obsolete
(6)
View All
Add attachment
proposed patch, testcase, etc.
David Grogan
Comment 1
2012-07-30 13:31:50 PDT
Created
attachment 155350
[details]
Patch
David Grogan
Comment 2
2012-07-30 13:39:25 PDT
Created
attachment 155351
[details]
Patch
WebKit Review Bot
Comment 3
2012-07-30 14:19:47 PDT
Comment on
attachment 155351
[details]
Patch
Attachment 155351
[details]
did not pass chromium-ews (chromium-xvfb): Output:
http://queues.webkit.org/results/13391443
New failing tests: storage/indexeddb/dont-fire-blocked-twice.html
WebKit Review Bot
Comment 4
2012-07-30 14:19:50 PDT
Created
attachment 155361
[details]
Archive of layout-test-results from gce-cr-linux-05 The attached test failures were seen while running run-webkit-tests on the chromium-ews. Bot: gce-cr-linux-05 Port: <class 'webkitpy.common.config.ports.ChromiumXVFBPort'> Platform: Linux-2.6.39-gcg-201203291735-x86_64-with-Ubuntu-10.04-lucid
David Grogan
Comment 5
2012-07-30 14:21:03 PDT
Ah yes, this won't run until shared.js from 92560 is in.
Joshua Bell
Comment 6
2012-08-15 16:23:09 PDT
This happens because we'll try a delete, it's blocked, fire blocked event, queue a pending delete it, dequeue the pending delete, try again, it's still blocked, fire (second) blocked event?
David Grogan
Comment 7
2012-08-15 16:26:22 PDT
(In reply to
comment #6
)
> This happens because we'll try a delete, it's blocked, fire blocked event, queue a pending delete it, dequeue the pending delete, try again, it's still blocked, fire (second) blocked event?
Correct.
David Grogan
Comment 8
2012-08-15 16:28:28 PDT
(In reply to
comment #6
)
> This happens because we'll try a delete, it's blocked, fire blocked event, queue a pending delete it, dequeue the pending delete, try again, it's still blocked, fire (second) blocked event?
We could fiddle with the logic in IDBDatabaseBackendImpl, or we could take the easy route and make IDBRequest drop blocked events after the first.
Joshua Bell
Comment 9
2012-08-15 16:36:57 PDT
I want to fiddle with the logic in IDBDatabaseBackendImpl. :) Looking at the spec, for open() and deleteDatabase() the terminology used is "The method then queues up an operation to run the steps for XXXing a database." We implement this with the pending calls mechanism and multiple queues. We use the same methods for the initial call (open, deleteDatabase) and when we dequeue the events to try again, which is how we hit this. One bit of cleanup might be to split those into deleteDatabase/deleteDatabaseInternal (like we do for put/putInternal in IDBObjectStore); in the spec, the steps for open/versionchange/delete are broken into two parts by a "wait until..." phrase. Parts before that should be in the (e.g.) deleteDatabase; the "wait until..." test could be in the processPendingCalls, and the rest in deleteDatabaseInternal.
Joshua Bell
Comment 10
2012-08-15 16:37:26 PDT
Um, but waiting until "upgradeneeded" is DONE DONE DONE first, of course.
Joshua Bell
Comment 11
2012-08-16 14:56:48 PDT
Playing with this a bit, the following pattern seems to work: void deleteDatabase(callbacks); // steps before the "wait" predicate bool isDeleteDatabaseBlocked(); // implements the "wait" predicate void deleteDatabaseFinal(callbacks); // steps after the "wait" predicate deleteDatabase(callbacks) adds a PendingDeleteDatabase object to the queue, then immediately calls processPendingCalls. Repeat for open, openWithVersion, setVersion, etc. Note that openWithVersion may in turn spawn a setIntVersion, which itself needs to be split up. The relevant chunk of processPendingCalls then becomes: if (isDeleteDatabaseBlocked()) return; while (!m_pendingDeleteDatabaseCalls.isEmpty()) { PendingDeleteDatabase pending = m_pendingDeleteDatabaseCalls.takeFirst(); deleteDatabaseFinal(pending.callbacks); } The version change bits (int and string) are the complicated ones, but it looks like this would simplify things overall.
Joshua Bell
Comment 12
2012-08-16 16:30:06 PDT
Created
attachment 158936
[details]
Patch
Joshua Bell
Comment 13
2012-08-16 16:33:47 PDT
Whoops, didn't mean to overwrite the tests in Patch #2. This is just a work-in-progress to show what I was thinking. Untested and won't even compile.
Joshua Bell
Comment 14
2012-08-23 16:07:57 PDT
Created
attachment 160272
[details]
Patch
Joshua Bell
Comment 15
2012-08-23 16:12:49 PDT
Another work-in-progress. Includes the tests (which pass!) from the first patches. Runs, but a handful of tests differ in output due to the order in which various database lifecycle events are delivered. Unclear if this is desirable or not. This patch also aggressively renames many methods (runIntVersionChangeTransaction => setIntVersion, setVersionInternal => setVersionTask, resetVersion => resetVersionAbortTask, etc) just to retain my sanity. We probably want to table this patch and just use it as a guide, doing the refactoring more slowly and maintaining test compatibility the whole time.
Joshua Bell
Comment 16
2012-08-24 12:39:44 PDT
Created
attachment 160475
[details]
Patch
Joshua Bell
Comment 17
2012-08-24 12:42:45 PDT
Latest patch is a subset of the previous, built from scratch, plus the tests. This just splits up deleteDatabase() into deleteDatabase()/isDeleteDatabaseBlocked()/deleteDatabaseFinal() and adjusts processPendingCalls() accordingly to resolve the bug. Some minor renaming is done (XXXInternal -> XXXTask), but leaving other cleanup for later. dgrogan@ - please take a look (We should check the flakiness dashboard before/after this lands.)
David Grogan
Comment 18
2012-08-24 14:26:24 PDT
(In reply to
comment #17
)
> (We should check the flakiness dashboard before/after this lands.)
Anecdote: the first time I ran the layout tests with this patch key-generator.html timed out. The second and third time it passed.
WebKit Review Bot
Comment 19
2012-08-24 14:39:28 PDT
Comment on
attachment 160475
[details]
Patch
Attachment 160475
[details]
did not pass chromium-ews (chromium-xvfb): Output:
http://queues.webkit.org/results/13593317
New failing tests: storage/indexeddb/factory-deletedatabase-interactions.html
WebKit Review Bot
Comment 20
2012-08-24 14:39:31 PDT
Created
attachment 160501
[details]
Archive of layout-test-results from gce-cr-linux-07 The attached test failures were seen while running run-webkit-tests on the chromium-ews. Bot: gce-cr-linux-07 Port: <class 'webkitpy.common.config.ports.ChromiumXVFBPort'> Platform: Linux-2.6.39-gcg-201203291735-x86_64-with-Ubuntu-10.04-lucid
Joshua Bell
Comment 21
2012-08-24 14:41:04 PDT
(In reply to
comment #19
)
> New failing tests: > storage/indexeddb/factory-deletedatabase-interactions.html
That's interesting. Passes locally. So why is it now flaky?
David Grogan
Comment 22
2012-08-24 17:31:04 PDT
Comment on
attachment 160475
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=160475&action=review
> LayoutTests/storage/indexeddb/factory-deletedatabase-interactions-expected.txt:46 > +'h.setVersion.onsuccess'
When run as a browser test, h.setVersion.onsuccess shows up right before 'h.onversionchange'.
Joshua Bell
Comment 23
2012-08-28 10:37:08 PDT
(In reply to
comment #22
)
> (From update of
attachment 160475
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=160475&action=review
> > > LayoutTests/storage/indexeddb/factory-deletedatabase-interactions-expected.txt:46 > > +'h.setVersion.onsuccess' > > When run as a browser test, h.setVersion.onsuccess shows up right before 'h.onversionchange'.
Fun. With this patch: In DRT the call order is: IDBDatabase::setVersion IDBDatabaseBackendImpl::setVersion IDBFactory::deleteDatabase IDBDatabaseBackendImpl::deleteDatabase
>> callbacks->onVersionChange()
IDBDatabaseBackendImpl::setVersionInternal (via task timer)
>> callbacks->onSuccess()
In Chromium the call order can instead be: IDBDatabase::setVersion IDBDatabaseBackendImpl::setVersion (via sync IPC) IDBFactory::deleteDatabase IDBDatabaseBackendImpl::setVersionInternal (via task timer)
>> callbacks->onSuccess()
IDBDatabaseBackendImpl::deleteDatabase (via async IPC)
>> callbacks->onVersionChange()
Without this patch, the deleteDatabase is silently delayed by a running/pending setVersion rather than having a blocked event. One approach might be to have the success callback fired by the setVersion method rather than the setVersionInternal method.
Joshua Bell
Comment 24
2012-08-28 10:43:31 PDT
> One approach might be to have the success callback fired by the setVersion method rather than the setVersionInternal method.
Bleah, can't do that since the transaction may be arbitrarily delayed by others on the same connection.
Joshua Bell
Comment 25
2012-12-18 15:46:26 PST
Created
attachment 180044
[details]
Patch
Joshua Bell
Comment 26
2012-12-18 15:50:57 PST
dgrogan@ - can you take a look? I made sure the tests pass in both test_shell and content_shell - there are difference in event logging in this sequence: openReq = indexedDB.open("db"); openReq.onupgradeneeded = function() { db = openReq.result; delReq = indexedDB.deleteDatabase("db"); db.onversionchange = function() { db.close(); }; delReq.onsuccess = logSuccessEvent; }; openReq.onerror = logErrorEvent; In content_shell the openReq.onerror fires before delReq.onsuccess. In test_shell it's the other way around.
David Grogan
Comment 27
2012-12-19 12:30:07 PST
Comment on
attachment 180044
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=180044&action=review
> Source/WebCore/ChangeLog:11 > + are also now sent out immediately when a "versionchange" transaction is running, rather
Do you know why we ever entered that limbo state instead of sending out events immediately? I looked at an old spec from when setVersion was still around but that doesn't mention waiting for versionchange transactions either.
> LayoutTests/storage/indexeddb/deletedatabase-delayed-by-open-and-versionchange-expected.txt:-16 > -versionChangeComplete = true
Curious, do you know what FF and IE do here?
> LayoutTests/storage/indexeddb/resources/intversion-delete-in-upgradeneeded-abort.js:6 > +description("Test that a deleteDatabase called while handling an upgradeneeded event is queued and fires its events at the right time");
I haven't diff'd them, but what's the difference between this and intversion-delete-in-upgradeneeded? Can you update this description?
> LayoutTests/storage/indexeddb/resources/intversion-delete-in-upgradeneeded.js:18 > var sawFirstUpgradeNeeded = false;
It looks like there is no "secondUpgradeNeeded", could you change this to sawUpgradeNeeded while you're in here?
Joshua Bell
Comment 28
2012-12-19 14:47:49 PST
Comment on
attachment 180044
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=180044&action=review
>> Source/WebCore/ChangeLog:11 >> + are also now sent out immediately when a "versionchange" transaction is running, rather > > Do you know why we ever entered that limbo state instead of sending out events immediately? I looked at an old spec from when setVersion was still around but that doesn't mention waiting for versionchange transactions either.
My guess is that the deleteDatabase implementation cribbed from setVersion, and with that API you have to support having the same connection call setVersion() twice, and in that case you probably don't want events.
>> LayoutTests/storage/indexeddb/deletedatabase-delayed-by-open-and-versionchange-expected.txt:-16 >> -versionChangeComplete = true > > Curious, do you know what FF and IE do here?
Ah, very good question. (*runs off and tries it*) IE10: * call open() * open request's onupgradeneeded fires * call deleteDatabase() * delete request's onblocked fires * versionchange transaction completes * open request's onsuccess fires * call close() * delete request's onsuccess fires FF17/19: * call open() * open request's onupgradeneeded fires * call deleteDatabase() * versionchange transaction completes * open request's onsuccess fires * call close() * delete request's onsuccess fires Confirmed w/ jonas on IRC that not firing "blocked" here is a FF bug. With this patch we match IE.
>> LayoutTests/storage/indexeddb/resources/intversion-delete-in-upgradeneeded-abort.js:6 >> +description("Test that a deleteDatabase called while handling an upgradeneeded event is queued and fires its events at the right time"); > > I haven't diff'd them, but what's the difference between this and intversion-delete-in-upgradeneeded? Can you update this description?
One calls close() within onversionchange, one calls close() in open-onsuccess. The former should abort the open, so I called that one "-abort". Calling close() in onversionchange is what this test originally did, but since onversionchange fires earlier it altered the flow of the test. So I moved close() to open-onsuccess, and added a separate test to capture calling close in onversionchange. Will update the desc and possibly rename the test(s).
>> LayoutTests/storage/indexeddb/resources/intversion-delete-in-upgradeneeded.js:18 >> var sawFirstUpgradeNeeded = false; > > It looks like there is no "secondUpgradeNeeded", could you change this to sawUpgradeNeeded while you're in here?
Will do.
Joshua Bell
Comment 29
2012-12-19 15:20:06 PST
Created
attachment 180236
[details]
Patch
Joshua Bell
Comment 30
2012-12-19 15:25:59 PST
tony@ - can you review?
WebKit Review Bot
Comment 31
2012-12-20 10:22:43 PST
Comment on
attachment 180236
[details]
Patch Clearing flags on attachment: 180236 Committed
r138268
: <
http://trac.webkit.org/changeset/138268
>
WebKit Review Bot
Comment 32
2012-12-20 10:22:48 PST
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug