WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
157702
Web Inspector: Filtering huge data grids should yield occasionally so the UI remains responsive
https://bugs.webkit.org/show_bug.cgi?id=157702
Summary
Web Inspector: Filtering huge data grids should yield occasionally so the UI ...
Matt Baker
Reported
2016-05-13 19:32:37 PDT
* SUMMARY Filtering huge data grids should yield occasionally so the UI remains responsive. Ideally the Inspector would have a generic mechanism whereby a task that processes a large number of items (such as data grid nodes) could yield control back to the runloop after a specified amount of time, before resuming processing.
Attachments
[Patch] Proposed Fix
(11.37 KB, patch)
2016-05-13 20:13 PDT
,
Matt Baker
no flags
Details
Formatted Diff
Diff
[Patch] Proposed Fix
(21.42 KB, patch)
2016-05-14 15:52 PDT
,
Matt Baker
no flags
Details
Formatted Diff
Diff
[Patch] Proposed Fix
(22.50 KB, patch)
2016-05-14 16:05 PDT
,
Matt Baker
no flags
Details
Formatted Diff
Diff
[Patch] Proposed Fix
(22.33 KB, patch)
2016-05-15 14:29 PDT
,
Matt Baker
no flags
Details
Formatted Diff
Diff
[Patch] Proposed Fix
(21.89 KB, patch)
2016-05-16 14:18 PDT
,
Matt Baker
no flags
Details
Formatted Diff
Diff
Proposed Fix v2
(25.30 KB, patch)
2016-05-16 16:31 PDT
,
Blaze Burg
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from ews113 for mac-yosemite
(1.59 MB, application/zip)
2016-05-16 17:21 PDT
,
Build Bot
no flags
Details
Archive of layout-test-results from ews103 for mac-yosemite
(1.41 MB, application/zip)
2016-05-16 17:36 PDT
,
Build Bot
no flags
Details
For Landing
(25.56 KB, patch)
2016-05-17 12:44 PDT
,
Blaze Burg
buildbot
: commit-queue-
Details
Formatted Diff
Diff
Archive of layout-test-results from ews102 for mac-yosemite
(1000.98 KB, application/zip)
2016-05-17 13:06 PDT
,
Build Bot
no flags
Details
Show Obsolete
(6)
View All
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2016-05-13 19:32:57 PDT
<
rdar://problem/26282898
>
Matt Baker
Comment 2
2016-05-13 20:13:20 PDT
Created
attachment 278914
[details]
[Patch] Proposed Fix
Joseph Pecoraro
Comment 3
2016-05-13 20:42:00 PDT
Comment on
attachment 278914
[details]
[Patch] Proposed Fix View in context:
https://bugs.webkit.org/attachment.cgi?id=278914&action=review
r=me, but we really should have tests that do basic coverage of the new class.
> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:26 > +WebInspector.BatchedTaskController = class BatchedTaskController extends WebInspector.Object
This could really use some tests! - tasks that don't end up yielding - tasks that do end up yielding - stopped by user and used again
> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:32 > + console.assert(delegate && typeof delegate.batchedTaskControllerProcessItem === "function", "Missing delegate implementing 'batchedTaskControllerProcessItem'");
Nit: console.assert(timeLimitPerBatch > 0)
> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:50 > + if (this._processing) > + return;
Nit: console.assert(!this._processing); Otherwise seems we should just ignore the new tasks in this case so there might be a silent error somewhere if this is called multiple times. And therefore probably a getter for processing would make sense.
> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:100 > + while (!this._batchGenerator.next().done) { > + this._batchTimeoutIdentifier = setTimeout(() => { this._processBatch(); }, 0); > + return; > + }
Nit: "if" instead of "while" would be clearer.
> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:130 > +};
This class is really clean, nice!
Matt Baker
Comment 4
2016-05-13 21:50:15 PDT
Comment on
attachment 278914
[details]
[Patch] Proposed Fix View in context:
https://bugs.webkit.org/attachment.cgi?id=278914&action=review
>> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:26 >> +WebInspector.BatchedTaskController = class BatchedTaskController extends WebInspector.Object > > This could really use some tests! > > - tasks that don't end up yielding > - tasks that do end up yielding > - stopped by user and used again
There are tests a plenty, I just ran webkit-patch from the wrong directory.
Timothy Hatcher
Comment 5
2016-05-14 07:50:07 PDT
Comment on
attachment 278914
[details]
[Patch] Proposed Fix View in context:
https://bugs.webkit.org/attachment.cgi?id=278914&action=review
Very cool! Nice use of generators.
> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:126 > + let stoppedByUser = this._stoppedByUser;
stoppedByClient? The "user" might not be involved.
> Source/WebInspectorUI/UserInterface/Views/DataGrid.js:1749 > + this._filterDidModifyNodeInCurrentBatch = false;
You should reset this before filtering starts too, to be on the safe side.
Matt Baker
Comment 6
2016-05-14 15:52:52 PDT
Created
attachment 278949
[details]
[Patch] Proposed Fix
Matt Baker
Comment 7
2016-05-14 15:55:37 PDT
Comment on
attachment 278914
[details]
[Patch] Proposed Fix View in context:
https://bugs.webkit.org/attachment.cgi?id=278914&action=review
>> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:126 >> + let stoppedByUser = this._stoppedByUser; > > stoppedByClient? The "user" might not be involved.
processingCancelled?
Matt Baker
Comment 8
2016-05-14 16:05:03 PDT
Created
attachment 278950
[details]
[Patch] Proposed Fix
Timothy Hatcher
Comment 9
2016-05-14 17:52:47 PDT
Comment on
attachment 278950
[details]
[Patch] Proposed Fix View in context:
https://bugs.webkit.org/attachment.cgi?id=278950&action=review
> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:91 > + this._processingCancelled = true;
_processingStopped?
Matt Baker
Comment 10
2016-05-14 18:32:18 PDT
Comment on
attachment 278950
[details]
[Patch] Proposed Fix View in context:
https://bugs.webkit.org/attachment.cgi?id=278950&action=review
>> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:91 >> + this._processingCancelled = true; > > _processingStopped?
I think cancelled makes it clear that the operation was stopped before finishing.
Timothy Hatcher
Comment 11
2016-05-14 19:12:36 PDT
Comment on
attachment 278950
[details]
[Patch] Proposed Fix View in context:
https://bugs.webkit.org/attachment.cgi?id=278950&action=review
>>> Source/WebInspectorUI/UserInterface/Controllers/BatchedTaskController.js:91 >>> + this._processingCancelled = true; >> >> _processingStopped? > > I think cancelled makes it clear that the operation was stopped before finishing.
Then maybe the method should match? cancelProcessing()
Matt Baker
Comment 12
2016-05-15 14:29:16 PDT
Created
attachment 278980
[details]
[Patch] Proposed Fix
Matt Baker
Comment 13
2016-05-15 14:29:52 PDT
Went with startTask/cancelTask.
Blaze Burg
Comment 14
2016-05-16 11:04:40 PDT
Comment on
attachment 278980
[details]
[Patch] Proposed Fix View in context:
https://bugs.webkit.org/attachment.cgi?id=278980&action=review
I have an idea for how to make this even cleaner, will post a patch to save you some time.
> Source/WebInspectorUI/UserInterface/Views/DataGrid.js:1734 > + batchedTaskControllerProcessItem(node)
Delegate methods need to pass the delegating instance as the first argument.
Matt Baker
Comment 15
2016-05-16 14:18:55 PDT
Created
attachment 279045
[details]
[Patch] Proposed Fix
Matt Baker
Comment 16
2016-05-16 14:20:34 PDT
I think this patch should be considered as-is. Adding support for multiple tasks would require a token to be returned from startTask, and passed to delegate methods. The same thing can be accomplished by instantiating multiple YieldableTask objects.
Blaze Burg
Comment 17
2016-05-16 16:31:01 PDT
Created
attachment 279065
[details]
Proposed Fix v2
Blaze Burg
Comment 18
2016-05-16 16:35:30 PDT
Comment on
attachment 279065
[details]
Proposed Fix v2 I went a slightly different direction here, because I think it will be easier to use: - YieldableTasks don't require a controller, but still use the delegate approach - They cannot be reused - The items iterator is passed at construction time Also addressed some style and correctness things: - Don't use 'batch' anywhere unless referring to something coalesced, like events - Check to see if cancelled before *and* after processing an item - delegate methods pass the delegating object as first parameter - try naming generator functions as createIteratorForXXX, use call instead of bind. - Delay notifying delegate about finishing when task is cancelled This gets us multiple tasks per object for free, more or less, in case we need to do that in the future. It also simplifies the lifetime of tasks so they cannot be accidentally leaked or reused.
Blaze Burg
Comment 19
2016-05-16 16:36:51 PDT
(In reply to
comment #16
)
> I think this patch should be considered as-is. Adding support for multiple > tasks would require a token to be returned from startTask, and passed to > delegate methods. The same thing can be accomplished by instantiating > multiple YieldableTask objects.
Right. The only thing I needed to change to get this was the name, really. Also, passing the delegating object in case there is more than one task. The rest is pretty much the same.
Timothy Hatcher
Comment 20
2016-05-16 17:00:25 PDT
Comment on
attachment 279065
[details]
Proposed Fix v2 View in context:
https://bugs.webkit.org/attachment.cgi?id=279065&action=review
> Source/WebInspectorUI/UserInterface/Base/YieldableTask.js:72 > + function* createIteratorForProcessingItems()
I think "createIteratorFor" is confusing. I would call this "processingItemsIterator".
> Source/WebInspectorUI/UserInterface/Base/YieldableTask.js:93 > + this._willYield(returnedItems, elapsedTime); > + yield;
Newline before?
> Source/WebInspectorUI/UserInterface/Base/YieldableTask.js:106 > + this._pendingItemsIterator = createIteratorForProcessingItems.call(this);
I suppose this is why you used create. I am surprised call() works… maybe I need to read up on generators.
> Source/WebInspectorUI/UserInterface/Base/YieldableTask.js:137 > + _willYield(processedItems, elapsedTime)
_didYield? It is confusing since this calls yieldableTaskDidYield.
> Source/WebInspectorUI/UserInterface/Views/DataGrid.js:1744 > + function *createIteratorForNodesToBeFiltered()
I would call this nodesToBeFilteredIterator.
> Source/WebInspectorUI/UserInterface/Views/DataGrid.js:1760 > + let options = { > + workInterval: 100, > + };
Inline it. Having it broken out makes me hate options arguments.
Build Bot
Comment 21
2016-05-16 17:21:30 PDT
Comment on
attachment 279065
[details]
Proposed Fix v2
Attachment 279065
[details]
did not pass mac-debug-ews (mac): Output:
http://webkit-queues.webkit.org/results/1333465
New failing tests: inspector/unit-tests/yieldable-task.html
Build Bot
Comment 22
2016-05-16 17:21:33 PDT
Created
attachment 279072
[details]
Archive of layout-test-results from ews113 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-debug-ews. Bot: ews113 Port: mac-yosemite Platform: Mac OS X 10.10.5
Build Bot
Comment 23
2016-05-16 17:36:36 PDT
Comment on
attachment 279065
[details]
Proposed Fix v2
Attachment 279065
[details]
did not pass mac-ews (mac): Output:
http://webkit-queues.webkit.org/results/1333569
New failing tests: inspector/unit-tests/yieldable-task.html
Build Bot
Comment 24
2016-05-16 17:36:39 PDT
Created
attachment 279074
[details]
Archive of layout-test-results from ews103 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews103 Port: mac-yosemite Platform: Mac OS X 10.10.5
Matt Baker
Comment 25
2016-05-16 19:47:52 PDT
(In reply to
comment #19
)
> (In reply to
comment #16
) > > I think this patch should be considered as-is. Adding support for multiple > > tasks would require a token to be returned from startTask, and passed to > > delegate methods. The same thing can be accomplished by instantiating > > multiple YieldableTask objects. > > Right. The only thing I needed to change to get this was the name, really. > Also, passing the delegating object in case there is more than one task. The > rest is pretty much the same.
Both of those items were addressed in the patch under
comment 15
.
Blaze Burg
Comment 26
2016-05-17 09:49:22 PDT
(In reply to
comment #25
)
> (In reply to
comment #19
) > > (In reply to
comment #16
) > > > I think this patch should be considered as-is. Adding support for multiple > > > tasks would require a token to be returned from startTask, and passed to > > > delegate methods. The same thing can be accomplished by instantiating > > > multiple YieldableTask objects. > > > > Right. The only thing I needed to change to get this was the name, really. > > Also, passing the delegating object in case there is more than one task. The > > rest is pretty much the same. > > Both of those items were addressed in the patch under
comment 15
.
Ugh! For some reason I didn't get any emails about all the subsequent patches that you wrote after the first one. Sorry for wasting your time; I thought you were working on other things at the time.
Blaze Burg
Comment 27
2016-05-17 09:50:17 PDT
(In reply to
comment #24
)
> Created
attachment 279074
[details]
> Archive of layout-test-results from ews103 for mac-yosemite > > The attached test failures were seen while running run-webkit-tests on the > mac-ews. > Bot: ews103 Port: mac-yosemite Platform: Mac OS X 10.10.5
Looks like the DidFinish callback is getting called twice, probably because more than one place is trying to send that during teardown.
Blaze Burg
Comment 28
2016-05-17 12:41:03 PDT
Comment on
attachment 279065
[details]
Proposed Fix v2 View in context:
https://bugs.webkit.org/attachment.cgi?id=279065&action=review
>> Source/WebInspectorUI/UserInterface/Base/YieldableTask.js:106 >> + this._pendingItemsIterator = createIteratorForProcessingItems.call(this); > > I suppose this is why you used create. I am surprised call() works… maybe I need to read up on generators.
Invoking a generator function creates a new iterator instance with its own state. This is basically a factory method. Once we have more examples in the code base, we should have a team discussion about the style to use for generators. Ref: "A generator is a special type of function that works as a factory for iterators."
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
> Source/WebInspectorUI/UserInterface/Base/YieldableTask.js:120 > + setTimeout(() => { this._didFinish(); }, 0);
It turns out this is unnecessary and responsible for the test flakiness. I will remove it before landing.
>> Source/WebInspectorUI/UserInterface/Base/YieldableTask.js:137 >> + _willYield(processedItems, elapsedTime) > > _didYield? It is confusing since this calls yieldableTaskDidYield.
There's no way to notify after the actual yield as the iterator's context will be suspended. So we set up state as if the yield happened, and then notify.
Blaze Burg
Comment 29
2016-05-17 12:44:26 PDT
Created
attachment 279150
[details]
For Landing
Build Bot
Comment 30
2016-05-17 13:06:40 PDT
Comment on
attachment 279150
[details]
For Landing
Attachment 279150
[details]
did not pass mac-ews (mac): Output:
http://webkit-queues.webkit.org/results/1337857
Number of test failures exceeded the failure limit.
Build Bot
Comment 31
2016-05-17 13:06:43 PDT
Created
attachment 279155
[details]
Archive of layout-test-results from ews102 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews102 Port: mac-yosemite Platform: Mac OS X 10.10.5
Blaze Burg
Comment 32
2016-05-17 14:37:22 PDT
Committed
r201047
: <
http://trac.webkit.org/changeset/201047
>
Alexey Proskuryakov
Comment 33
2016-05-25 13:23:47 PDT
The new test is somewhat flaky:
https://webkit-test-results.webkit.org/dashboards/flakiness_dashboard.html#showAllRuns=true&tests=inspector%2Funit-tests%2Fyieldable-task.html
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