Uh oh!
There was an error while loading. Please reload this page.
Implement the Happy Eye Balls RFC's - #196
Conversation
4662be9 to
ac92884CompareWyriHaximus
commented
Mar 5, 2019
This PR is now ready for review. A follow up will be filed to replace the |
89c9769 to
e4676eaCompare46a9866 to
25c1ecdCompareWyriHaximus
commented
May 2, 2019
clue
left a comment
There was a problem hiding this comment.
@WyriHaximus Thank you very much for working on this, this is one of the features that is very high on my personal wishlist! ❤️
However, I realize that the implementation is anything but trivial. I've added some remarks to some places that look odd to me, perhaps you can take a look?
That being said, once all implementation issues are resolved, I wonder what's the best path forward to ensure a safe rollout of this feature in the future? Perhaps it makes sense to first enable this without IPv6 support to see the initial implementation does not break any existing implementations? I can see some (legacy) use cases where it may be desirable to explicitly disable IPv6 because the downstream application might not be IPv6-ready? (think database fields storing an address in a fixed length field)
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
3117a07 to
8fa1d3eCompareWyriHaximus
commented
May 18, 2019
🎉 !!!
Thanks for the review, I've addressed those points.
Not entirely sure yet how to do that. What I want to do is write a follow up PR that initially will go full in on happy-eyeballs. And then we'll comes up during the discussion on that PR how we're shaping that. Because I'm pretty sure we can solve this with a flag on the |
clue
left a comment
There was a problem hiding this comment.
@WyriHaximus Thanks for the update! This PR/implementation is not exactly trivial, so I've added some remarks to see if we can avoid some of its complexity. Let me know what you think about it.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
WyriHaximus
commented
Jun 27, 2019
It isn't trivial at all. I'll be adding links to certain implementation details linking to the RFC('s) where applicable to understand the why for those things. |
1326b88 to
335cdcbCompareWyriHaximus
commented
Jun 27, 2019
@clue oki updated to after your comments |
clue
left a comment
There was a problem hiding this comment.
@WyriHaximus Thank you very much, the additional comments really help, I think we're slowly getting there!
I've noticed this code currently has ~85% coverage and I've added some remarks to perhaps improve this.
Consider my structural concerns resolved, I'd love to get this in once we've added some additional tests, given the inherent complexity of this algorithm 👍
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
WyriHaximus
commented
Jun 28, 2019
@clue working on the tests now, noticed the same thing this morning. 15% coverage to go 🎉 |
c886e32 to
d227b9cCompareWyriHaximus
commented
Aug 25, 2019
✅
✅
✅
❌ (working on it) |
dcc19c6 to
22d2f6bCompareWyriHaximus
commented
Aug 29, 2019
✅ |
clue
left a comment
There was a problem hiding this comment.
@WyriHaximus Thanks for the update! All my local tests have succeeded with the updated version 👍
Unfortunately, the test suite now takes ~1.8 minutes(!) to run, whereas the old version took ~8 seconds. Perhaps rebase on #207 which should further improve this and then take a look at why the tests are so slow?
The test suite should probably use a mocked look (unless it's an integration test) and use $promise->then($this->expectCallableOneWith($expectedValue)) instead of running and awaiting the loop. In particular, all timers should be avoided unless absolutely required.
| if ($that->timer instanceof TimerInterface) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Can you take a look at this again? I can't reproduce this locally anymore, but I don't see any change here?
| $ipv4Deferred = new Promise\Deferred(); | ||
| $deferred = new Promise\Deferred(); | ||
| $timer = $that->loop->addTimer($that::RESOLVE_WAIT, function () use ($deferred, $ips) { |
There was a problem hiding this comment.
Promise cancellation doesn't seem to cancel this timer?
| if (count($ipv4) > 0) { | ||
| $this->tcp->expects($this->at($i++))->method('connect')->with($this->equalTo('scheme://' . array_shift($ipv4) . ':80/?hostname=google.com'))->will($this->returnValue(Promise\resolve())); | ||
| } | ||
| } |
There was a problem hiding this comment.
Not a big fan of having this logic in the test suite. It's my understanding this should be rather static and/or multiple independent tests. After all, where are the tests for this test suite? 👀 I'm okay with this for now.
There was a problem hiding this comment.
Not a big fan of it either. But this lets us test different lenghth IPvX responses against several tests. This uncovered certain edge cases in the past and help me first the issue you commented about on line 60.
e73fa33 to
888941fCompareWyriHaximus
commented
Sep 20, 2019
@clue decreased tests time, they're still slower then before but that's due to the timings involved. |
clue
commented
Sep 21, 2019
@WyriHaximus Can confirm the test time is now down to ~50s on my machine. There still seem to be plenty of timers, so I would still suggest mocking the loop and explicitly invoking the timer callback like this: $loop = $this->createMock(LoopInterface::class);
$timer = null;
$loop->expects($this->once())->method('addTimer')->with(2.0, $this->callback(function ($cb) use (&$timer) {
$timer = $cb;
returntrue;
}));
// continue with test$this->assertNotNull($timer);
$timer(); |
WyriHaximus
commented
Sep 22, 2019
@clue yeah this is going to be |
888941f to
29695e1CompareWyriHaximus
commented
Sep 22, 2019
@clue went for a slightly different approach that still does a full run with an actual event loop and timers, but I've speed it up instead by a factor of 10. |
clue
left a comment
There was a problem hiding this comment.
@WyriHaximus Thanks for keeping up with this, I can confirm that test time changed to ~13s (~8s prior to this patch) 👍 Now let's get this feature shipped! ![]()
| It will then replace the hostname in the destination URI with this IP's and | ||
| append a `hostname` query parameter and pass this updated URI to the underlying | ||
| connector. | ||
| The Happy Eye Balls algorythm describes looking the IPv6 and IPv4 address for |
| The `HappyEyeBallsConnector` class implements the | ||
| [`ConnectorInterface`](#connectorinterface) and allows you to create plaintext | ||
| TCP/IP connections to any hostname-port-combination. Internally it implements the | ||
| happy eyeballs algorythm from [`RFC6555`](https://tools.ietf.org/html/rfc6555) and |
WyriHaximus
commented
Oct 23, 2019
So @jsor spotted two typo's after approving, will fix those before merging 👍 |
By using the happy eye balls algorithm as described in RFC6555 and RFC8305 it will connect to the quickest responding server with a preference for IPv6.
29695e1 to
f2b5fc4Compare
By using the happy eye balls algorythm as descripted in
RFC6555andRFC8305it will connect to the quickest responding server with apreference for IPv6.