RESOLVED FIXED101483
IndexedDB: Replace use of ScriptExecutionContext::Task (Part 1)
https://bugs.webkit.org/show_bug.cgi?id=101483
Summary IndexedDB: Replace use of ScriptExecutionContext::Task (Part 1)
Joshua Bell
Reported 2012-11-07 10:02:10 PST
We use ScriptExecutionContext::Task in IDBTransactionBackendImpl to hold "tasks", but this pulls a lot of machinery in that we don't need e.g. ThreadSafeRefCounted, and so forth. Consider replacing this usage with something else - either a generic closure class, or operation-specific holders (e.g. ObjectStoreStorageOperation, ObjectStoreRetrievalOperation, etc). The latter is particularly appealing when we consider moving those to the front end as they would encapsulate the asynchronous logic (e.g. for an "add" you need to do at least one "get" to verify that the value is not present, more "gets" if there are "unique" indexes, then several "puts" - all of which may be async)
Attachments
Patch (12.59 KB, patch)
2012-11-28 17:21 PST, Joshua Bell
no flags
Patch (72.17 KB, patch)
2012-11-29 17:15 PST, Joshua Bell
no flags
Alec Flett
Comment 1 2012-11-07 13:22:52 PST
I believe this is also the last use of ScriptExecutionContext in the backend - so when this is fixed, all references to that should be removed (if anything, that's kind of a test if this bug is fixed or not)
Joshua Bell
Comment 2 2012-11-28 17:21:22 PST
Joshua Bell
Comment 3 2012-11-28 17:26:13 PST
Comment on attachment 176608 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=176608&action=review This is what I'm thinking about as a first step. This is hard to read as a unified diff, so try side-by-side... > Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:66 > +class IDBCursorBackendImpl::CursorIterationOperation A type is defined for each operation. Cursors end up being trickier than most since they have state, unlike store/index operations. > Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:71 > + return createCallbackTask(&CursorIterationOperation::perform, cursor, key, callbacks); This would be temporary for the first part of the refactoring - instead of returning an instance of this class, keep returning a ScriptExecutionContext::Task... > Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:75 > + static void perform(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> cursor, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) But move the implementation here - this used to be IDBCursorBackendImpl::continueInternal > Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:166 > + if (!m_transaction->scheduleTask(m_taskType, CursorIterationOperation::create(this, key, callbacks))) Sample call site. This would then remain unchanged even when the operation stopped being a ScriptExecutionContext::Task.
David Grogan
Comment 4 2012-11-29 11:18:17 PST
Comment on attachment 176608 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=176608&action=review Let me know if I've understood the direction or totally missed the boat. >> Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:66 >> +class IDBCursorBackendImpl::CursorIterationOperation > > A type is defined for each operation. Cursors end up being trickier than most since they have state, unlike store/index operations. Is the idea that there will be an Operation base class that this will derive from? Operation would have one substantive method, e.g. void perform(void)? >> Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:71 >> + return createCallbackTask(&CursorIterationOperation::perform, cursor, key, callbacks); > > This would be temporary for the first part of the refactoring - instead of returning an instance of this class, keep returning a ScriptExecutionContext::Task... When this class derives from Operation, the parameters will be copied to class data members? >> Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:166 >> + if (!m_transaction->scheduleTask(m_taskType, CursorIterationOperation::create(this, key, callbacks))) > > Sample call site. This would then remain unchanged even when the operation stopped being a ScriptExecutionContext::Task. scheduleTask will take a PassRefPtr<Operation> ?
Joshua Bell
Comment 5 2012-11-29 11:48:54 PST
Comment on attachment 176608 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=176608&action=review >>> Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:66 >>> +class IDBCursorBackendImpl::CursorIterationOperation >> >> A type is defined for each operation. Cursors end up being trickier than most since they have state, unlike store/index operations. > > Is the idea that there will be an Operation base class that this will derive from? > Operation would have one substantive method, e.g. void perform(void)? Yes, exactly. If/when the backing store becomes asynchronous (to implement caching), the operations would end up with more internal state, callbacks, etc. with perform(void) as the entry point. But while the backing store is synchronous, it can all live in perform(void). >>> Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:71 >>> + return createCallbackTask(&CursorIterationOperation::perform, cursor, key, callbacks); >> >> This would be temporary for the first part of the refactoring - instead of returning an instance of this class, keep returning a ScriptExecutionContext::Task... > > When this class derives from Operation, the parameters will be copied to class data members? Exactly. >>> Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp:166 >>> + if (!m_transaction->scheduleTask(m_taskType, CursorIterationOperation::create(this, key, callbacks))) >> >> Sample call site. This would then remain unchanged even when the operation stopped being a ScriptExecutionContext::Task. > > scheduleTask will take a PassRefPtr<Operation> ? Correct.
David Grogan
Comment 6 2012-11-29 11:53:50 PST
Sounds great. LGTM
Alec Flett
Comment 7 2012-11-29 12:26:36 PST
Comment on attachment 176608 [details] Patch I'm ambivalent: the functional programmer in me cringes at all the extra classes, but the C++ developer in me appreciates the encapsulation. so LGTM!
Joshua Bell
Comment 8 2012-11-29 17:15:04 PST
Joshua Bell
Comment 9 2012-11-29 17:17:39 PST
dgrogan@, alecflett@ - please take a look. One nice thing I realized is that just as today the Task is implicitly called with ScriptExecutionContext* as the first parameter, eventually Operation::perform() can be called with IDBTransactionBackendImpl as the parameter so operations don't need to carry it with them.
David Grogan
Comment 10 2012-11-30 12:07:16 PST
Comment on attachment 176854 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=176854&action=review LGTM > Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:-256 > - RefPtr<IDBObjectStoreBackendImpl> objectStore = this; I'm 95% sure these are unnecessary and not self references to guard against deletion in some weird situation. I'm assuming you convinced yourself of something similar?
Joshua Bell
Comment 11 2012-11-30 13:13:26 PST
(In reply to comment #10) > > Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:-256 > > - RefPtr<IDBObjectStoreBackendImpl> objectStore = this; > > I'm 95% sure these are unnecessary and not self references to guard against deletion in some weird situation. I'm assuming you convinced yourself of something similar? Yes. I think it was either stylistic or perhaps createCallbackTask() didn't convert raw pointers to PassRefPtrs at some point, but they were not used consistently.
Joshua Bell
Comment 12 2012-11-30 13:14:03 PST
tony@ - can you r?
Tony Chang
Comment 13 2012-11-30 13:25:45 PST
Comment on attachment 176854 [details] Patch This seems like an improvement to static callbacks on the implementations, although it is a bit verbose.
WebKit Review Bot
Comment 14 2012-11-30 13:49:19 PST
Comment on attachment 176854 [details] Patch Clearing flags on attachment: 176854 Committed r136272: <http://trac.webkit.org/changeset/136272>
WebKit Review Bot
Comment 15 2012-11-30 13:49:24 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.