Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 158
Implement the Happy Eye Balls RFC's#196
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
WyriHaximus commented Feb 27, 2019 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you take a look at this again? I can't reproduce this locally anymore, but I don't see any change here?
| $ipv4Deferred = newPromise\Deferred(); | ||
| $deferred = newPromise\Deferred(); | ||
| $timer = $that->loop->addTimer($that::RESOLVE_WAIT, function () use ($deferred, $ips){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Promise cancellation doesn't seem to cancel this timer?
WyriHaximusSep 20, 2019 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed that
| 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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! ![]()
README.md Outdated
| 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
algorithm
README.md Outdated
| 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
algorithm
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.