Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: use flatten protocol #9783

Merged
merged 22 commits into from Nov 4, 2019
Merged

core: use flatten protocol #9783

merged 22 commits into from Nov 4, 2019

Conversation

connorjclark
Copy link
Collaborator

@connorjclark connorjclark commented Oct 4, 2019

Chromium CL

We need to migrate to the flatten protocol for a few reasons:

  1. Non-flatten is officially deprecated.
  2. It's required to fix a protocol bug in DevTools.
  3. Wrapping the protocol via Target.sendMessageToTarget / Target.receivedMessageFromTarget is a waste of bandwidth and processing time.

For this initial pass, I created a new sendCommandToSession method so the ~200 usages of sendCommand don't need to change. Could split out the very common code between sendCommand / sendCommandToSession, but I don't think we combine it into one interface (the rest params make an optional parameter impossible).

Open problems:

  1. For CLI + Chrome Stable, the oopif smoke fixture never seems to render the iframe. The iframe remains white the entire run and just hangs. No issue for Canary or Beta.

image

  1. The oopif smoke fixture seems to take a few seconds longer. Why?

  2. DevTools crashes the renderer process when the mobile emulation Lighthouse applies is reverted. This happens even with just the LH bundle changes (no other devtools frontend changes).

tracing_service_impl.cc: Tracing session 1 ended, total sessions:0
Received signal 11 SEGV_MAPERR 000000000000
#0 0x7f0837a456e9 base::debug::CollectStackTrace()
#1 0x7f083797ef63 base::debug::StackTrace::StackTrace()
#2 0x7f0837a45271 base::debug::(anonymous namespace)::StackDumpSignalHandler()
#3 0x7f082c0b03a0 <unknown>
#4 0x7f083590b279 content::RenderWidgetScreenMetricsEmulator::DisableAndApply()
#5 0x7f08358fb700 content::RenderWidget::OnDisableDeviceEmulation()
#6 0x7f08358fb647 IPC::MessageT<>::Dispatch<>()
#7 0x7f08358faa4c content::RenderWidget::OnMessageReceived()
#8 0x7f0836170511 IPC::ChannelProxy::Context::OnDispatchMessage()
#9 0x7f08379e406f base::TaskAnnotator::RunTask()
#10 0x7f08379f86ca base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl()
#11 0x7f08379f84a8 base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoSomeWork()
#12 0x7f083799f15a base::MessagePumpDefault::Run()
#13 0x7f08379f8ee9 base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run()
#14 0x7f08379c79c7 base::RunLoop::Run()
#15 0x7f083590ec61 content::RendererMain()
#16 0x7f0835a25dfe content::RunZygote()
#17 0x7f0835a27064 content::ContentMainRunnerImpl::Run()
#18 0x7f08294428ad service_manager::Main()
#19 0x7f0835a25381 content::ContentMain()
#20 0x55b6ba09146f ChromeMain
#21 0x7f082ae6e52b __libc_start_main
#22 0x55b6ba0912da _start
  r8: 00007f08358fb6e0  r9: 0000000000000000 r10: 0000000000000002 r11: 0000000000000003
 r12: 0000000000000000 r13: 0000069d5a620738 r14: 00007f08358fb6e0 r15: 0000069d59f98800
  di: 0000000000000000  si: 0000069d5a620738  bp: 00007fff05c25860  bx: 0000000000000000
  dx: 0000069d59f98800  ax: 0000069d5a245a58  cx: 0000000000000000  sp: 00007fff05c25850
  ip: 00007f083590b279 efl: 0000000000010202 cgf: 002b000000000033 erf: 0000000000000004
 trp: 000000000000000e msk: 0000000000000000 cr2: 0000000000000000
[end of stack trace]
Calling _exit(1). Core file will not be generated.

I left some useful debugging code commented out. Will remove after these open problems are resolved.

Timings:

CHROME_PATH=~/Desktop/opt/google/chrome-beta/google-chrome-beta node lighthouse-core/scripts/compare-timings.js --name base --collect -n 10 --urls http://localhost:10200/oopif.html https://www.nyt.com https://www.sfgate.com/

image

https://gist.githubusercontent.com/connorjclark/b6ed524cfd9cbead8186e219a0f74f59/raw/a089d238eb166ff3954ba7918f61736effcbb664/gistfile1.txt

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very fast @connorjclark nice work! 💨

This should not merge until the Chromium changes are ready.

The Chromium changes in that CL look like they include an LH roll, is that a circularish dependency? They also seem frontend only, does that mean that the bug...

DevTools crashes the renderer process when the mobile emulation Lighthouse applies is reverted. This happens even with just the LH bundle changes (no other devtools frontend changes).

will need to be fixed by a separate CL?

Basically, what should we reviewers do for you now? :)

lighthouse-core/gather/connections/connection.js Outdated Show resolved Hide resolved
lighthouse-core/gather/connections/connection.js Outdated Show resolved Hide resolved
lighthouse-core/gather/driver.js Outdated Show resolved Hide resolved
lighthouse-core/gather/driver.js Show resolved Hide resolved
@@ -40,7 +40,7 @@ class ResponseCompression extends Gatherer {
const unoptimizedResponses = [];

networkRecords.forEach(record => {
// Ignore records from OOPIFs
// Ignore records from child targets (OOPIFS).
if (record.sessionId) return;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requests from the main target still won't have a sessionId will they?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct.

@connorjclark
Copy link
Collaborator Author

connorjclark commented Oct 4, 2019

Very fast @connorjclark nice work!

Thanks :)

The Chromium changes in that CL look like they include an LH roll, is that a circularish dependency?

I mean we shouldn't land this in LH until we fix the crashing bug in DevTools. Otherwise, we won't be able to release to DevTools. The CL doesn't have to land first.

They also seem frontend only, does that mean that the ...
will need to be fixed by a separate CL?

We should have a fix ready to go before landing any of this.

Basically, what should we reviewers do for you now? :)

Mostly, we should start bike-shedding the necessary interface changes to sendCommand.

Any idea why the crash is happening? That's what I'm up to today.

@connorjclark
Copy link
Collaborator Author

  1. DevTools crashes the renderer process when the mobile emulation Lighthouse applies is reverted. This happens even with just the LH bundle changes (no other devtools frontend changes).

Update on this. This is unrelated to these changes. Can be repro'd by merging master LH into ToT Chromium. AFAICT, an additional Session/EmulationHandler.cc is sending an extra DisableDeviceEmulation IPC. The second "disable" crashes, I guess because the delegate has already been destroyed. Without rolling LH master, I only see a single EmulationHandler.

some logging I found helpful, for later.

./out/Linux/chrome --enable-logging=stderr --v=1 2>&1 | grep  connor

# plz someone teach me better chromium debugging

diff --git a/content/browser/devtools/protocol/emulation_handler.cc b/content/browser/devtools/protocol/emulation_handler.cc
index b2ffbf81c4c0..60f3c3be8fb1 100644
--- a/content/browser/devtools/protocol/emulation_handler.cc
+++ b/content/browser/devtools/protocol/emulation_handler.cc
@@ -170,6 +170,8 @@ Response EmulationHandler::SetDeviceMetricsOverride(
     Maybe<bool> dont_set_visible_size,
     Maybe<Emulation::ScreenOrientation> screen_orientation,
     Maybe<protocol::Page::Viewport> viewport) {
+  LOG(WARNING) << "connor EmulationHandler::SetDeviceMetricsOverride "<<device_emulation_enabled_;
+
   const static int max_size = 10000000;
   const static double max_scale = 10;
   const static int max_orientation_angle = 360;
@@ -290,6 +292,7 @@ Response EmulationHandler::ClearDeviceMetricsOverride() {
     return Response::OK();
   if (!host_)
     return Response::Error("Can't find the associated web contents");
+  LOG(WARNING) << "connor EmulationHandler::ClearDeviceMetricsOverride "<<device_emulation_enabled_;
   GetWebContents()->ClearDeviceEmulationSize();
   device_emulation_enabled_ = false;
   device_emulation_params_ = blink::WebDeviceEmulationParams();
@@ -337,6 +340,7 @@ void EmulationHandler::SetDeviceEmulationParams(
     const blink::WebDeviceEmulationParams& params) {
   bool enabled = params != blink::WebDeviceEmulationParams();
   if (params != device_emulation_params_) {
+    LOG(WARNING) << "connor EmulationHandler::SetDeviceEmulationParams " << device_emulation_enabled_;
     device_emulation_enabled_ = enabled;
     device_emulation_params_ = params;
     UpdateDeviceEmulationState();
@@ -376,6 +380,9 @@ void EmulationHandler::UpdateDeviceEmulationState() {
   // Device emulation only happens on the main frame.
   if (!host_->frame_tree_node()->IsMainFrame())
     return;
+  
+  LOG(WARNING) << "connor EmulationHandler::UpdateDeviceEmulationState " << " " << this << " --- " << device_emulation_enabled_;
+  base::debug::StackTrace().PrintWithPrefix("connor ");

@connorjclark
Copy link
Collaborator Author

connorjclark commented Oct 8, 2019

It's #9377. yay...I solved it? :/ Let's merge this plz.

@connorjclark
Copy link
Collaborator Author

Must merge #9193 first. Flatten won't work with the extension.

@connorjclark
Copy link
Collaborator Author

These changes won't work with M77 (see failing oopif smoke test). I don't know why. We don't really need it to (78 comes
out Oct 15, and that works), except that CI uses M77.

@connorjclark
Copy link
Collaborator Author

connorjclark commented Oct 8, 2019

Bisected to https://chromium.googlesource.com/chromium/src/+log/87e8027a5738d0daf1dbb7e350693eff745b5961..abc13cb07e3b62fa21003cfc38fcb5c2fab06aab

Only DevTools change: https://chromium.googlesource.com/chromium/src/+/001ceaaaa92cf3dbfa573fb40c3a682e0dc72fd7

This is what fixed the issue.

Snippet from CL:

When devtools auto-attaches to OOPIF, it will trigger several calls to AttachToAgent. The session in that case is not suspended, and all waiting messages are forwarded to the new render frame host (when it is ready to commit navigation). After the navigation, ResumeSendingMessagesToAgent will be called and should be ignored as the session is not suspended and all messages have been forwarded to the RFH.

Bisect command:

python tools/bisect-builds.py -b 681094 -g 693954 -a mac64 -c \
 'bash -c "CHROME_PATH=%p node /Users/cjamcl/src/lighthouse/lighthouse-cli http://localhost:10200/oopif.html"'

You are probably looking for a change made after 691305 (known bad), but no later than 691327 (first known good).

@connorjclark
Copy link
Collaborator Author

connorjclark commented Oct 8, 2019

So here are the pertinent dates and constraints:

Oct 15: M78 stable release. To avoid breaking master LH on Stable Chrome, must land this PR after this date.

Also Oct 15: scheduled LH release.

Oct 17: M79 branch. To fix auditing OOPIFs in the Audits panel, must land this PR and the associated Chromium CL by this date (plus, roll LH). This is a soft deadline - we can probably get a merge OK'd a bit after easily enough.

Removing Draft status, since the big two issues have been addressed. PTAL

@connorjclark connorjclark marked this pull request as ready for review October 8, 2019 23:31
@connorjclark
Copy link
Collaborator Author

@connorjclark this doesn't pass our OOPIF smoketest in travis, seems like there's something to be fixed and/or something local you need to push?

See #9783 (comment) and the two comments following. These changes won't work in CI until the new stable release tomorrow.

EDIT: are we still waiting on the Chromium change to be merged? I'm still not 100% clear on the sequence needed here

The Chromium change has been merged already.

Co-Authored-By: Patrick Hulce <patrick.hulce@gmail.com>
@patrickhulce
Copy link
Collaborator

See #9783 (comment) and the two comments following. These changes won't work in CI until the new stable release tomorrow.

Oh right, sorry! I guess we won't get green builds until #9193 is merged anyway?

This approach LGTM though 👍

@paulirish
Copy link
Member

LGTM from me.
The chromium breakage is certainly making this annoying.

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright LGTM assuming we can get a green build out of the new stable :)

* @param {boolean} enable
* @return {boolean}
* @private
*/
_shouldToggleDomain(domain, enable) {
const enabledCount = this._domainEnabledCounts.get(domain) || 0;
_shouldToggleDomain(domain, sessionId, enable) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time to add tests for this functionality? :D

should hopefully be pretty easy with the new mock capabilities and can just sendCommand('Network.enable') or whatever to make sure it doesn't turn off to early :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time to add tests for this functionality? :D

should hopefully be pretty easy with the new mock capabilities and can just sendCommand('Network.enable') or whatever to make sure it doesn't turn off to early :)

+1 to this. After a certain number of enables and disables, watching when the actual command is sent shouldn't end up too bad, I hope.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM3 with an extra test or two

Nice and neat and great to be able to delete a good chunk of code

});
});

it('enables the Network domain for iframes of iframes of iframes', async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was the earlier discussions about tests about this? It seems a shame to lose this assertion (and we still have to make sure to recursively enable attaching, so could still conceivably be broken at some point)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path for attaching to an iframe target is now the exact same as attaching to an iframe's iframe target, so I don't see functionality in having a test for this. I removed the test because it needed to be rewritten to continue working, and how to do so was a head-scratcher.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path for attaching to an iframe target is now the exact same as attaching to an iframe's iframe target, so I don't see functionality in having a test for this.

one level deep appears to be in gotoURL while 2+ levels deep appears to happen in _handleTargetAttached, I believe?

@patrickhulce could maybe help make the call/give an idea for testing

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

goToURL calls Target.setAutoAttach on the main target, but the first and subsequent targets will be via _handleTargetAttached. I suppose it was this way before too, but what's different now is that we don't have to worry about the complicated message routing - I believe this test existed just to verify that mechanism.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, it's having a test of the inductive step that would feel good, even if it's a trivial difference from the initial attachment

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

though I guess what you may be saying is that since we don't keep any hierarchy of the child targets (e.g. looking at openerId), having a child target of a child target is indistinguishable from having two sibling child targets in terms of protocol traffic we'd care about.

That's a good point and that means the second one is a really trivial difference from the first, but it seems ok to include a two-child-target case, which would also provide a nice tripwire/starting point if and when we ever start treating fourth-party, etc content differently and need to track the target hierarchy

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mostly lean on @connorjclark's side of this that there is no difference to driver in this case now and we're basically relying on chrome to do the right thing and send us nested targets, mocking Chrome doing the right thing doesn't feel super valuable since it ends up being indistinguishable to us

I feel comfortable enough with the grandchild OOPIF smoke test we have that exercises this, but a two-child-target test case seems reasonable as the test for this anyhow, so might as well :)

* @param {boolean} enable
* @return {boolean}
* @private
*/
_shouldToggleDomain(domain, enable) {
const enabledCount = this._domainEnabledCounts.get(domain) || 0;
_shouldToggleDomain(domain, sessionId, enable) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time to add tests for this functionality? :D

should hopefully be pretty easy with the new mock capabilities and can just sendCommand('Network.enable') or whatever to make sure it doesn't turn off to early :)

+1 to this. After a certain number of enables and disables, watching when the actual command is sent shouldn't end up too bad, I hope.

devtools-bot pushed a commit to ChromeDevTools/devtools-frontend that referenced this pull request Oct 17, 2019
Also cherry-picked:

GoogleChrome/lighthouse#9377
GoogleChrome/lighthouse#9783

Bug: 772558
Bug: 1011228

Change-Id: Ibe9e4b3849940bf86c666bf55698a9ced4253fd3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1867249
Reviewed-by: Erik Luo <luoe@chromium.org>
Commit-Queue: Connor Clark <cjamcl@google.com>
Cr-Original-Commit-Position: refs/heads/master@{#707110}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 5f16f693662c78467b8ae531a3f03e37ccf94c69
babot pushed a commit to binaryage/dirac that referenced this pull request Oct 18, 2019
Also cherry-picked:

GoogleChrome/lighthouse#9377
GoogleChrome/lighthouse#9783

Bug: 772558
Bug: 1011228

Change-Id: Ibe9e4b3849940bf86c666bf55698a9ced4253fd3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1867249
Reviewed-by: Erik Luo <luoe@chromium.org>
Commit-Queue: Connor Clark <cjamcl@google.com>
Cr-Commit-Position: refs/heads/master@{#707110}
@connorjclark
Copy link
Collaborator Author

Should start passing tomorrow :)

@connorjclark
Copy link
Collaborator Author

connorjclark commented Nov 4, 2019

This needs to land, or else it becomes the second PR that needs to be merged to releases for DevTools to work (the first being #9377)

@brendankenny
Copy link
Member

This needs to land, or else it becomes the second PR that needs to be merged to releases for DevTools to work

I see two official LGTMs and a third unofficial one, so... :P

@connorjclark connorjclark merged commit 7c16d34 into master Nov 4, 2019
@connorjclark connorjclark deleted the flatten branch November 4, 2019 21:49
connorjclark added a commit that referenced this pull request Nov 7, 2019
connorjclark added a commit that referenced this pull request Nov 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants