Bug 92897 - IndexedDB: Frontend and plumbing for integer versions
Summary: IndexedDB: Frontend and plumbing for integer versions
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: David Grogan
URL:
Keywords: WebExposed
: 89505 (view as bug list)
Depends on: 92560 92883
Blocks:
  Show dependency treegraph
 
Reported: 2012-08-01 12:09 PDT by David Grogan
Modified: 2012-08-21 15:27 PDT (History)
6 users (show)

See Also:


Attachments
Patch (80.41 KB, patch)
2012-08-01 12:16 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch (80.24 KB, patch)
2012-08-01 14:03 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch (84.81 KB, patch)
2012-08-14 16:06 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch (84.68 KB, patch)
2012-08-14 16:21 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch (84.73 KB, patch)
2012-08-14 16:37 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch (84.61 KB, patch)
2012-08-14 18:11 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch (85.27 KB, patch)
2012-08-15 18:45 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch (83.44 KB, patch)
2012-08-16 00:06 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch (83.41 KB, patch)
2012-08-16 17:48 PDT, David Grogan
no flags Details | Formatted Diff | Diff
Patch for landing (83.74 KB, patch)
2012-08-16 19:33 PDT, David Grogan
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Grogan 2012-08-01 12:09:36 PDT
IndexedDB: Frontend and plumbing for integer versions
Comment 1 David Grogan 2012-08-01 12:16:25 PDT
Created attachment 155858 [details]
Patch
Comment 2 David Grogan 2012-08-01 14:03:01 PDT
Created attachment 155881 [details]
Patch
Comment 3 David Grogan 2012-08-01 14:05:44 PDT
Josh, Alec, could you look at this?

This turns on integer versions in the front end.  This is mostly plumbing, but there are a few tricky bits.  E.g. not creating two IDBDatabaseBackendProxy objects for the same database.
Comment 4 David Grogan 2012-08-01 14:26:49 PDT
Oh, and after this patch, we should be close enough to remove the prefix.  There are still a few FAILs in the output, but nothing too serious.
Comment 5 David Grogan 2012-08-14 16:06:26 PDT
Created attachment 158433 [details]
Patch
Comment 6 David Grogan 2012-08-14 16:21:48 PDT
Created attachment 158438 [details]
Patch
Comment 7 David Grogan 2012-08-14 16:37:18 PDT
Created attachment 158443 [details]
Patch
Comment 8 Joshua Bell 2012-08-14 17:01:19 PDT
Comment on attachment 158433 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=158433&action=review

First batch of comments.

> Source/WebCore/Modules/indexeddb/IDBDatabase.cpp:314
> +    enqueueEvent(IDBUpgradeNeededEvent::create(existingVersion, requestedVersion, eventNames().versionchangeEvent));

Just checking - this is using IDBUpgradeNeededEvent for its (oldversion/newversion) payload; it may appear to script as an Event.type = "versionchange" (e.g. here) or an Event.type = "upgradeneeded"?

> Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.cpp:2
> + * Copyright (C) 2011 Google Inc. All rights reserved.

Date for new file: 2012

> Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.cpp:63
> +    ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_result);

Call to shouldEnqueueEvent() here?

> Source/WebCore/Modules/indexeddb/IDBRequest.cpp:286
> +        idbDatabase->registerFrontendCallbacks();

The registerFrontendCallbacks() call is in both the if and else paths, factor out?

> Source/WebCore/Modules/indexeddb/IDBRequest.cpp:527
> +    ASSERT_WITH_MESSAGE(m_readyState == PENDING || m_didFireUpgradeNeededEvent, "When queueing event %s, m_readyState was %d", event->type().string().utf8().data(), m_readyState);

This is odd. Is m_readyState not PENDING between "upgradeneeded" and success? I would have assumed that like "blocked", the IDBRequest doesn't flip to "done" until the "success" fires, in which case this isn't necessary. (But code is needed to say "if upgradeneeded, don't set done because we'll fire again". That would also eliminate the need to override shouldEnqueueEvent()

Hrm... it looks like the spec doesn't actually specify when the "done flag" should be set for an IDBOpenDBRequest - bleah.

> Source/WebCore/Modules/indexeddb/IDBRequest.h:106
> +    void clearTransactionProperty();

Naming nit: Maybe just clearTransaction()?

> Source/WebCore/Modules/indexeddb/IDBTransaction.cpp:387
> +    // FIXME: Try to construct a test where |this| outlives openDBRequest and we

Is clearing the request->transaction reference out required by the spec?

> Source/WebCore/Modules/indexeddb/IDBUpgradeNeededEvent.cpp:2
> + * Copyright (C) 2011 Google Inc. All rights reserved.

Year for new file: 2012.

> Source/WebCore/Modules/indexeddb/IDBUpgradeNeededEvent.h:2
> + * Copyright (C) 2011 Google Inc. All rights reserved.

Year for new file: 2012.
Comment 9 David Grogan 2012-08-14 18:08:13 PDT
Comment on attachment 158433 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=158433&action=review

>> Source/WebCore/Modules/indexeddb/IDBDatabase.cpp:314
>> +    enqueueEvent(IDBUpgradeNeededEvent::create(existingVersion, requestedVersion, eventNames().versionchangeEvent));
> 
> Just checking - this is using IDBUpgradeNeededEvent for its (oldversion/newversion) payload; it may appear to script as an Event.type = "versionchange" (e.g. here) or an Event.type = "upgradeneeded"?

event.type will yield "versionchange" but String(event) will yield "[object IDBUpgradeNeededEvent]".  I'm not sure how important it is to make String(event) return "[object IDBVersionChangeEvent]".

>> Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.cpp:2
>> + * Copyright (C) 2011 Google Inc. All rights reserved.
> 
> Date for new file: 2012

done.

>> Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.cpp:63
>> +    ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_result);
> 
> Call to shouldEnqueueEvent() here?

Done, thanks.

>> Source/WebCore/Modules/indexeddb/IDBRequest.cpp:286
>> +        idbDatabase->registerFrontendCallbacks();
> 
> The registerFrontendCallbacks() call is in both the if and else paths, factor out?

Done.

>> Source/WebCore/Modules/indexeddb/IDBRequest.cpp:527
>> +    ASSERT_WITH_MESSAGE(m_readyState == PENDING || m_didFireUpgradeNeededEvent, "When queueing event %s, m_readyState was %d", event->type().string().utf8().data(), m_readyState);
> 
> This is odd. Is m_readyState not PENDING between "upgradeneeded" and success? I would have assumed that like "blocked", the IDBRequest doesn't flip to "done" until the "success" fires, in which case this isn't necessary. (But code is needed to say "if upgradeneeded, don't set done because we'll fire again". That would also eliminate the need to override shouldEnqueueEvent()
> 
> Hrm... it looks like the spec doesn't actually specify when the "done flag" should be set for an IDBOpenDBRequest - bleah.

4.8.9.3 is
Fire a upgradeneeded event targeted at request. The event must use the IDBVersionChangeEvent interface and have the oldVersion property set to old version and have the newVersion property set to version. The readyState on the request is set to "done".

I interpreted the last sentence to mean that the done flag should be set to true when upgradeneeded is fired. Indeed, request.result is supposed to be available to the upgradeneeded handler. There's nothing to indicate that it should be reverted back to false, so I'm guessing it's supposed to stay true. I haven't checked FF though.

An additional wrinkle is that a complete event is fired at the version change transaction between upgradeneeded and success. The availability of request.result when that event is handled needs to be considered.  In this patch, clearTransactionProperty sets readyState = PENDING after complete is dispatched, just to avoid more uses of m_didFireUpgradeNeededEvent.

>> Source/WebCore/Modules/indexeddb/IDBRequest.h:106
>> +    void clearTransactionProperty();
> 
> Naming nit: Maybe just clearTransaction()?

Because this function did more than clear the transaction (it also resets readyState), I changed it to transactionDidDispatchCompleteOrAbort. Even less wieldy. Perhaps I should change it back to clearTransaction, not clear readyState, and add more m_readyState == PENDING || m_didFireUpgradeNeededEvent in place of m_readyState == PENDING.

>> Source/WebCore/Modules/indexeddb/IDBTransaction.cpp:387
>> +    // FIXME: Try to construct a test where |this| outlives openDBRequest and we
> 
> Is clearing the request->transaction reference out required by the spec?

Yeah, the last step in '"versionchange" transaction steps' (4.8.12, mentioned in the changelog) is:

When the transaction is finished, if these steps are run asynchronously, immediately set request's transaction property to null. This must be done in the same task as the task firing the complete or abort event, but after those events has been fired.

>> Source/WebCore/Modules/indexeddb/IDBUpgradeNeededEvent.cpp:2
>> + * Copyright (C) 2011 Google Inc. All rights reserved.
> 
> Year for new file: 2012.

done.

>> Source/WebCore/Modules/indexeddb/IDBUpgradeNeededEvent.h:2
>> + * Copyright (C) 2011 Google Inc. All rights reserved.
> 
> Year for new file: 2012.

done.
Comment 10 David Grogan 2012-08-14 18:11:02 PDT
Created attachment 158467 [details]
Patch
Comment 11 Joshua Bell 2012-08-15 11:33:37 PDT
(In reply to comment #9)
> event.type will yield "versionchange" but String(event) will yield "[object IDBUpgradeNeededEvent]".  I'm not sure how important it is to make String(event) return "[object IDBVersionChangeEvent]".

IMHO we can defer fixing until we remove setVersion().

Does the WebKitIDL attribute [InterfaceName=IDBVersionChangeEvent] specified on the interface happen to "just work"?
 
> > Hrm... it looks like the spec doesn't actually specify when the "done flag" should be set for an IDBOpenDBRequest - bleah.
> 
> 4.8.9.3 is
> Fire a upgradeneeded event targeted at request. The event must use the IDBVersionChangeEvent interface and have the oldVersion property set to old version and have the newVersion property set to version. The readyState on the request is set to "done".

Thanks, missed that.
 
> I interpreted the last sentence to mean that the done flag should be set to true when upgradeneeded is fired. 

Agreed.

> Indeed, request.result is supposed to be available to the upgradeneeded handler. 

Yeah, which explains it.

> There's nothing to indicate that it should be reverted back to false, so I'm guessing it's supposed to stay true. I haven't checked FF though.

I would agree that staying true makes sense...
 
> An additional wrinkle is that a complete event is fired at the version change transaction between upgradeneeded and success. The availability of request.result when that event is handled needs to be considered.  In this patch, clearTransactionProperty sets readyState = PENDING after complete is dispatched, just to avoid more uses of m_didFireUpgradeNeededEvent.

Bleah, messy whatever way we go. Bring the ambiguity up on the spec list?

It would be nice if we could flip it back to "pending" before enqueuing the success, since that simplifies the state machine of IDBRequest.

It looks like (in the latest patch) the m_didFireUpgradeNeededEvent flag is used only for asserting? Nice if we can keep it like that (although I hate tracking debug-only state).

> >> Source/WebCore/Modules/indexeddb/IDBRequest.h:106
> >> +    void clearTransactionProperty();
> > 
> > Naming nit: Maybe just clearTransaction()?
> 
> Because this function did more than clear the transaction (it also resets readyState), I changed it to transactionDidDispatchCompleteOrAbort.

FWIW the internal state enum in IDBTransaction.h calls this state "Finished", if that helps naming.
Comment 12 David Grogan 2012-08-15 15:24:08 PDT
(In reply to comment #11)
> (In reply to comment #9)
> > event.type will yield "versionchange" but String(event) will yield "[object IDBUpgradeNeededEvent]".  I'm not sure how important it is to make String(event) return "[object IDBVersionChangeEvent]".
> 
> Does the WebKitIDL attribute [InterfaceName=IDBVersionChangeEvent] specified on the interface happen to "just work"?

Seems to. Good stuff. Thanks.

> > An additional wrinkle is that a complete event is fired at the version change transaction between upgradeneeded and success. The availability of request.result when that event is handled needs to be considered.  In this patch, clearTransactionProperty sets readyState = PENDING after complete is dispatched, just to avoid more uses of m_didFireUpgradeNeededEvent.
> 
> Bleah, messy whatever way we go. Bring the ambiguity up on the spec list?

By ambiguity, you mean the value of readyState when the "complete" event is handled?

> 
> It would be nice if we could flip it back to "pending" before enqueuing the success, since that simplifies the state machine of IDBRequest.

We currently flip back to pending before *dispatching* the success event, but not before enqueueing it.  Flipping back to pending before enqueuing the success event would mean that the "complete" handler would not be able to access request.result, correct?

> It looks like (in the latest patch) the m_didFireUpgradeNeededEvent flag is used only for asserting? Nice if we can keep it like that (although I hate tracking debug-only state).

Yeah, it's just used in ASSERTs.

> 
> > >> Source/WebCore/Modules/indexeddb/IDBRequest.h:106
> > >> +    void clearTransactionProperty();
> > > 
> > > Naming nit: Maybe just clearTransaction()?
> > 
> > Because this function did more than clear the transaction (it also resets readyState), I changed it to transactionDidDispatchCompleteOrAbort.
> 
> FWIW the internal state enum in IDBTransaction.h calls this state "Finished", if that helps naming.
Comment 13 Joshua Bell 2012-08-15 15:29:03 PDT
(In reply to comment #12)
> 
> By ambiguity, you mean the value of readyState when the "complete" event is handled?

Yes.
 
> > 
> > It would be nice if we could flip it back to "pending" before enqueuing the success, since that simplifies the state machine of IDBRequest.
> 
> We currently flip back to pending before *dispatching* the success event, but not before enqueueing it.  Flipping back to pending before enqueuing the success event would mean that the "complete" handler would not be able to access request.result, correct?

Right, so depends on the discussion of readyState vs. "complete". Right now the assertions in IDBRequest can say "if you're going to enqueue or dispatch, you'd better be PENDING". I wasn't suggesting changes, just expressing the hope we can keep things simple.

(Given how messy IDBRequest::dispatchEvent is already, we can probably do a cleanup pass after everything is in; expose virtual helper functions that categorize events and what can be done when, etc.)
Comment 14 David Grogan 2012-08-15 18:45:22 PDT
Created attachment 158686 [details]
Patch
Comment 15 David Grogan 2012-08-15 18:47:29 PDT
(In reply to comment #11)
> > >> Source/WebCore/Modules/indexeddb/IDBRequest.h:106
> > >> +    void clearTransactionProperty();
> > > 
> > > Naming nit: Maybe just clearTransaction()?
> > 
> > Because this function did more than clear the transaction (it also resets readyState), I changed it to transactionDidDispatchCompleteOrAbort.
> 
> FWIW the internal state enum in IDBTransaction.h calls this state "Finished", if that helps naming.

I want to preserve the indication that it happens after the events are dispatched.  m_state = Finished happens before the events are dispatched.  Right now the name is transactionDidFinishAndDispatch.  Still ugh.
Comment 16 David Grogan 2012-08-16 00:06:46 PDT
Created attachment 158726 [details]
Patch
Comment 17 David Grogan 2012-08-16 17:48:46 PDT
Created attachment 158960 [details]
Patch
Comment 18 David Grogan 2012-08-16 18:03:58 PDT
Tony, could you review this?

It's huge but mostly simple.
Comment 19 Tony Chang 2012-08-16 18:23:25 PDT
Comment on attachment 158960 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=158960&action=review

If jsbell is happy, seems fine to me.

> LayoutTests/ChangeLog:11
> +        * storage/indexeddb/intversion-abort-in-initial-upgradeneeded-expected.txt:
> +        * storage/indexeddb/intversion-and-setversion-expected.txt:
> +        * storage/indexeddb/intversion-blocked-expected.txt:
> +        * storage/indexeddb/intversion-close-between-events-expected.txt:

Nit: Maybe explain some of the changes here.
Comment 20 David Grogan 2012-08-16 19:33:23 PDT
Created attachment 158981 [details]
Patch for landing
Comment 21 WebKit Review Bot 2012-08-16 21:21:56 PDT
Comment on attachment 158981 [details]
Patch for landing

Clearing flags on attachment: 158981

Committed r125850: <http://trac.webkit.org/changeset/125850>
Comment 22 WebKit Review Bot 2012-08-16 21:22:01 PDT
All reviewed patches have been landed.  Closing bug.
Comment 23 David Grogan 2012-08-21 15:27:18 PDT
*** Bug 89505 has been marked as a duplicate of this bug. ***