WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 203431
REGRESSION (
r250754
): web page using IDBIndex doesn't load occasionally
https://bugs.webkit.org/show_bug.cgi?id=203431
Summary
REGRESSION (r250754): web page using IDBIndex doesn't load occasionally
Sihui Liu
Reported
2019-10-25 13:00:15 PDT
Reproducible steps: 1. Open local test page in minibrowser: OpenSource/PerformanceTests/IndexedDB/basic/index-count-key.html 2. Nagivate to OpenSource/PerformanceTests/IndexedDB/basic/index-count.html (address bar) Result: second page does not load
Attachments
Patch
(37.58 KB, patch)
2019-10-31 15:37 PDT
,
Sihui Liu
no flags
Details
Formatted Diff
Diff
Patch
(43.66 KB, patch)
2019-10-31 15:58 PDT
,
Sihui Liu
no flags
Details
Formatted Diff
Diff
Patch
(43.73 KB, patch)
2019-11-01 17:15 PDT
,
Sihui Liu
no flags
Details
Formatted Diff
Diff
Patch
(54.33 KB, patch)
2019-11-04 20:21 PST
,
Sihui Liu
no flags
Details
Formatted Diff
Diff
Patch for landing
(53.87 KB, patch)
2019-11-05 10:01 PST
,
Sihui Liu
no flags
Details
Formatted Diff
Diff
Show Obsolete
(4)
View All
Add attachment
proposed patch, testcase, etc.
Sihui Liu
Comment 1
2019-10-25 13:26:08 PDT
Adding shouldPreventEnteringBackForwardCache_DEPRECATED() to return true in IDBIndex fixes the issue.
Chris Dumez
Comment 2
2019-10-25 13:28:42 PDT
(In reply to Sihui Liu from
comment #1
)
> Adding shouldPreventEnteringBackForwardCache_DEPRECATED() to return true in > IDBIndex fixes the issue.
This would not the right fix though, just to be clear.
Sihui Liu
Comment 3
2019-10-25 18:30:11 PDT
(In reply to Chris Dumez from
comment #2
)
> (In reply to Sihui Liu from
comment #1
) > > Adding shouldPreventEnteringBackForwardCache_DEPRECATED() to return true in > > IDBIndex fixes the issue. > > This would not the right fix though, just to be clear.
The cause is the IDBDatabase object is not destroyed and database connection stays open when user navigates to another page. When the second page tries to delete the database, it's blocked on the open connection. We have to close database connections on navigation, and this would change the state of the IDB DOM objects (open connection -> closed, ongoing transaction -> aborted, etc). If the state change is acceptable for page cache, we probably stop()/close() the IDBDatabase in suspend().
Sihui Liu
Comment 4
2019-10-25 18:33:46 PDT
(In reply to Sihui Liu from
comment #3
)
> (In reply to Chris Dumez from
comment #2
) > > (In reply to Sihui Liu from
comment #1
) > > > Adding shouldPreventEnteringBackForwardCache_DEPRECATED() to return true in > > > IDBIndex fixes the issue. > > > > This would not the right fix though, just to be clear. > > The cause is the IDBDatabase object is not destroyed and database connection > stays open when user navigates to another page. When the second page tries > to delete the database, it's blocked on the open connection. > > We have to close database connections on navigation, and this would change > the state of the IDB DOM objects (open connection -> closed, ongoing > transaction -> aborted, etc). If the state change is acceptable for page > cache, we probably stop()/close() the IDBDatabase in suspend().
Or maybe to invalidate the IDB objects when there are IDB changes from the new page, and discard page cache when there are invalidated IDB objects
Chris Dumez
Comment 5
2019-10-25 18:45:45 PDT
(In reply to Sihui Liu from
comment #4
)
> (In reply to Sihui Liu from
comment #3
) > > (In reply to Chris Dumez from
comment #2
) > > > (In reply to Sihui Liu from
comment #1
) > > > > Adding shouldPreventEnteringBackForwardCache_DEPRECATED() to return true in > > > > IDBIndex fixes the issue. > > > > > > This would not the right fix though, just to be clear. > > > > The cause is the IDBDatabase object is not destroyed and database connection > > stays open when user navigates to another page. When the second page tries > > to delete the database, it's blocked on the open connection. > > > > We have to close database connections on navigation, and this would change > > the state of the IDB DOM objects (open connection -> closed, ongoing > > transaction -> aborted, etc). If the state change is acceptable for page > > cache, we probably stop()/close() the IDBDatabase in suspend(). > > Or maybe to invalidate the IDB objects when there are IDB changes from the > new page, and discard page cache when there are invalidated IDB objects
We need to be careful about Web compatibility. I looked at the spec and found: """ A connection may be closed by a user agent in exceptional circumstances, for example due to loss of access to the file system, a permission change, or clearing of the origin’s storage. If this occurs the user agent must run close a database connection with the connection and with the forced flag set to true. """ It looks like "close a database connection" algorithm fires a "close" event so I guess the page would at least get notified on resume that the connection was closed and could re-open it itself. Ideally though, the Web page would not have to do anything and things would recover nicely by themselves upon resuming. That said, I have no idea if it is feasible here.
Chris Dumez
Comment 6
2019-10-28 12:35:33 PDT
Sihui, are you looking into fixing this?
Sihui Liu
Comment 7
2019-10-31 15:37:58 PDT
Created
attachment 382510
[details]
Patch
Sihui Liu
Comment 8
2019-10-31 15:58:40 PDT
Created
attachment 382514
[details]
Patch
Sihui Liu
Comment 9
2019-11-01 17:15:39 PDT
Created
attachment 382659
[details]
Patch
Chris Dumez
Comment 10
2019-11-02 11:59:41 PDT
Comment on
attachment 382659
[details]
Patch r- due to EWS failures (crashes look related).
Sihui Liu
Comment 11
2019-11-04 10:46:42 PST
(In reply to Chris Dumez from
comment #10
)
> Comment on
attachment 382659
[details]
> Patch > > r- due to EWS failures (crashes look related).
That crash is not caused by this patch:
https://bugs.webkit.org/show_bug.cgi?id=201744
. It's been around for a while and I've not reproduced successfully on a local build yet.
Brady Eidson
Comment 12
2019-11-04 12:55:14 PST
Comment on
attachment 382659
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=382659&action=review
> Source/WebCore/Modules/indexeddb/IDBDatabase.cpp:470 > + if (scriptExecutionContext()->isDocument()) {
If the global object that has the open database handle is a web worker (i.e. not a Document) then it will not do the right thing here. IDB is frequently used by workers, so we definitely have to handle that case. I wonder if Workers know if their owning document is in the page cache? If not, I wonder how hard it would be to teach them? Regardless, we need to solve that.
> Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h:88 > + void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, bool connectionClosedOnBehalfOfServer);
Hard to read with trues and falses scattered about. Let's make the bool be an enum.
Chris Dumez
Comment 13
2019-11-04 12:58:27 PST
Comment on
attachment 382659
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=382659&action=review
>> Source/WebCore/Modules/indexeddb/IDBDatabase.cpp:470 >> + if (scriptExecutionContext()->isDocument()) { > > If the global object that has the open database handle is a web worker (i.e. not a Document) then it will not do the right thing here. > > IDB is frequently used by workers, so we definitely have to handle that case. > > I wonder if Workers know if their owning document is in the page cache? > If not, I wonder how hard it would be to teach them? > > Regardless, we need to solve that.
Workers do not know that their document is in the page cache. When their document is in the page cache, the worker thread is paused and therefore no code can run.
Chris Dumez
Comment 14
2019-11-04 13:07:02 PST
Comment on
attachment 382659
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=382659&action=review
>>> Source/WebCore/Modules/indexeddb/IDBDatabase.cpp:470 >>> + if (scriptExecutionContext()->isDocument()) { >> >> If the global object that has the open database handle is a web worker (i.e. not a Document) then it will not do the right thing here. >> >> IDB is frequently used by workers, so we definitely have to handle that case. >> >> I wonder if Workers know if their owning document is in the page cache? >> If not, I wonder how hard it would be to teach them? >> >> Regardless, we need to solve that. > > Workers do not know that their document is in the page cache. When their document is in the page cache, the worker thread is paused and therefore no code can run.
This means that if someones posts a task on the worker thread to run IDBDatabase::fireVersionChangeEvent(), that task won't be processed until *after* the document has been restored from the backforward cache.
Brady Eidson
Comment 15
2019-11-04 13:21:09 PST
(In reply to Chris Dumez from
comment #14
)
> Comment on
attachment 382659
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=382659&action=review
> > >>> Source/WebCore/Modules/indexeddb/IDBDatabase.cpp:470 > >>> + if (scriptExecutionContext()->isDocument()) { > >> > >> If the global object that has the open database handle is a web worker (i.e. not a Document) then it will not do the right thing here. > >> > >> IDB is frequently used by workers, so we definitely have to handle that case. > >> > >> I wonder if Workers know if their owning document is in the page cache? > >> If not, I wonder how hard it would be to teach them? > >> > >> Regardless, we need to solve that. > > > > Workers do not know that their document is in the page cache. When their document is in the page cache, the worker thread is paused and therefore no code can run. > > This means that if someones posts a task on the worker thread to run > IDBDatabase::fireVersionChangeEvent(), that task won't be processed until > *after* the document has been restored from the backforward cache.
Right - And that means the new page's IDB use would be blocked just like it is today. Sihui and I figured a good fix for this case IRL. I think she's implementing it now.
Sihui Liu
Comment 16
2019-11-04 20:21:05 PST
Created
attachment 382804
[details]
Patch
Alex Christensen
Comment 17
2019-11-04 20:23:56 PST
Comment on
attachment 382804
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=382804&action=review
> Source/WebCore/Modules/indexeddb/IndexedDB.h:127 > +template<> struct EnumTraits<WebCore::IndexedDB::ConnectionClosedOnBehalfOfServer> {
If you use bool as the storage type for this enum class, then it will be smaller and this will be unnecessary.
Sihui Liu
Comment 18
2019-11-05 10:01:38 PST
Created
attachment 382831
[details]
Patch for landing
WebKit Commit Bot
Comment 19
2019-11-05 10:25:52 PST
Comment on
attachment 382831
[details]
Patch for landing Clearing flags on attachment: 382831 Committed
r252060
: <
https://trac.webkit.org/changeset/252060
>
WebKit Commit Bot
Comment 20
2019-11-05 10:25:54 PST
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 21
2019-11-05 10:26:29 PST
<
rdar://problem/56909138
>
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