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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

core(oopif): attach to all descendants #7608

Merged
merged 6 commits into from
Mar 22, 2019
Merged

Conversation

patrickhulce
Copy link
Collaborator

@patrickhulce patrickhulce commented Mar 20, 2019

Summary
OK, OOPIF fixes attempt 479 :)

The good news: this is now 100% contained in driver.js and should work in all our environments 馃帀

The bad news: it's kinda ugly to look at and reason about (we have to do nested Target.sendMessageToTarget calls and unpack nested receiveMessageFromTarget messages)

Related Issues/PRs
#7517 #7566 also #6922 #6337 #6078

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

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

this is dope. nice work sorting all this out

lighthouse-core/gather/driver.js Outdated Show resolved Hide resolved
lighthouse-core/gather/driver.js Outdated Show resolved Hide resolved
@patrickhulce
Copy link
Collaborator Author

DZL, do a barrel roll

@devtools-bot
Copy link

DZL is done! Go check it out http://lh-dzl-7608.surge.sh

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.

very nice and clean solution! Going to be a little hard to reason about how it works a month or two from now, but that seems pretty inherent to what we have to do to make it work :/

Not-directly-this-PR-related thoughts:

  • I think we should consider splitting driver in the near future, like we've talked about a few times. This PR could make a nice split point, wrapping connection as it's passed into the constructor with a multiTargetConnection that hides this logic inside

  • I'm a little concerned about the scalability of handling each type of Target message passed up individually, so we should think about what we want to do (transparent like these Network events? And/or some kind of explicit session handling for gatherers that want to ask a particular target a question?).

    Not just academic, @paulirish is already talking about injecting some code in there to do some SW shenanigans 馃槶

lighthouse-core/lib/network-recorder.js Show resolved Hide resolved
lighthouse-core/gather/driver.js Show resolved Hide resolved
lighthouse-core/gather/driver.js Outdated Show resolved Hide resolved
lighthouse-core/gather/driver.js Show resolved Hide resolved
lighthouse-core/gather/driver.js Outdated Show resolved Hide resolved
lighthouse-core/gather/driver.js Outdated Show resolved Hide resolved
lighthouse-core/gather/driver.js Outdated Show resolved Hide resolved
this._handleTargetAttached(protocolMessage.params, sessionIdPath);
}

if (protocolMessage.method.startsWith('Network')) {
Copy link
Member

Choose a reason for hiding this comment

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

emit this one so it's handled as usual instead of handling it here?

Copy link
Collaborator Author

@patrickhulce patrickhulce Mar 21, 2019

Choose a reason for hiding this comment

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

well our current handling isn't actually on driver events it's off the connection event, and I thought it would be weird to forcibly emit an event from within driver on the connection. but I guess you disagree?

馃 hopes the answer isn't let's refactor this whole thing now ;)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

compromise: moved this bit into a function that gets called by both?

Copy link
Member

Choose a reason for hiding this comment

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

well our current handling isn't actually on driver events it's off the connection event

ah, I had forgotten about this. I also remembered we did it the way it is because you can't listen to Network.*, so we needed to listen to protocolevent, which is too bad.

moved this bit into a function that gets called by both?

sounds perfect

lighthouse-core/gather/driver.js Outdated Show resolved Hide resolved

// We receive messages from the outermost subtarget which wraps the messages from the inner subtargets.
// We are recursively processing them from outside in, so build the list of parentSessionIds accordingly.
const sessionIdPath = parentSessionIds.concat([sessionId]);
Copy link
Member

Choose a reason for hiding this comment

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

can we just push() like normal people :P

(also, if we're only ever going to look at it in reverse order, unshift() and remove the reverse() instead?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

you think a normal person would prefer a list that's mutated through these layers on top of everything else that's going on!?! 馃槺

you feelin' alright @brendankenny? you might want to go to a doctor to get that checked out 馃槢

the reverse point is worth discussing though :)

IMO, it's easiest to keep track of what the list looks like based on how it's being built, not how it's being used. This way you do not need to be thinking about the complexities of another function just to understand what's going inside this one. The fact that it gets used to build the messages inside out is an implementation detail of its sibling function (afterall I could have written sendMessageToTarget in a recursive way in which case the list wouldn't need to be reversed). WDYT?

Copy link
Member

Choose a reason for hiding this comment

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

you think a normal person would prefer a list that's mutated through these layers on top of everything else that's going on!?! 馃槺

lol, I forgot about that benefit of concat :P :P

IMO, it's easiest to keep track of what the list looks like based on how it's being built, not how it's being used.

i mean, [sessionId, ... parentSessionIds] doesn't seem any more surprising to me than the other way around, honestly. I do find

The fact that it gets used to build the messages inside out is an implementation detail of its sibling function (afterall I could have written sendMessageToTarget in a recursive way in which case the list wouldn't need to be reversed).

compelling, but I think the justification works for either approach (if _handleReceivedMessageFromTarget was written differently :). The main downside of the current approach is the .slice().reverse(), which adds mental overhead to the code we actually have written

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

you had me at [sessionId, ...parentSessionIds] :) done

@@ -5,6 +5,6 @@
</head>
<body>
<h1>Hello frames</h1>
<iframe name="oopif" src="https://airhorner.com"></iframe>
<iframe name="oopif" src="https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/" style="width: 100vw; height: 100vh;"></iframe>
Copy link
Member

Choose a reason for hiding this comment

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

also, should we just be making our own OOPIF here rather than relying on this page having another nested one? We could do a page on the other port to go cross origin (assuming that triggers OOP) and have that embed the youtube video, for instance

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wish, I tried like 15 different combinations but localhost never seems to be oopif'd on its own, so we need at least one publicly hosted page that then also iframes a google-y origin that will guarantee 2 separate processes beyond our localhost one

// Events from subtargets will be stringified and sent back on `Target.receivedMessageFromTarget`.
// We want to receive information about network requests from iframes, so enable the Network domain.
this.sendMessageToTarget(sessionIdPath, 'Network.enable');
this.sendMessageToTarget(sessionIdPath, 'Runtime.runIfWaitingForDebugger');
Copy link
Member

Choose a reason for hiding this comment

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

do this after setAutoAttach (as the last thing), much like how devtools frontend does this right now.

image

also.. can you add a comment that explains what this does. (Basically the target was put into a suspended/paused state with waitForDebuggerOnStart: true and this resumes it.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

was too fast for ya already done! :) but yeah i'll add a comment

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.

just the lint error left

LGTM!

lighthouse-core/gather/driver.js Show resolved Hide resolved
@devtools-bot
Copy link

DZL is done! Go check it out http://lh-dzl-7608.surge.sh

@connorjclark
Copy link
Collaborator

For future sleuthing (blame sends you to this PR): I asked Patrick "Why didn't we use flatten?"

Answer: the extension protocol API only allows for "send message to target interface". see #7566 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants