-
-
Notifications
You must be signed in to change notification settings - Fork 62
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
Retry on zero bytes written #149
Retry on zero bytes written #149
Conversation
We've had that a long time already, and 3 seems to be a good value. I don't think it needs to be customizable. |
@kelunik where do you think I had the inspiration from 😉 |
This is an interesting one, thanks for filing! When exactly does this problem show up, i.e. how can we reproduce this and be sure the suggested fix works? This hasn't shown up before, is this platform-specific behavior or does this only happen for certain streams (SSL/TLS wrappers, process pipes etc.)? I understand the underlying |
Reproducing this issue seems to be quite hard (for others at least). Then, sending data through that connection made it close at some point. That was no longer the issue with this fix in place. |
I couldn't reproduce this. Literally had to give @mpociot a file to test and confirm it would fix this specific problem.
Because if we don't, there will be endless retries. While testing @mpociot would restart the server giving me a broken connection, so it hits the |
@mpociot Interesting, seems to confirm my suspicion this could be related to TLS streams. I assume this only happens when you print "a lot" of data, i.e. buffers start to become full(er)? Can you post some details about your platform? PHP version + extensions, OS? How do you reproduce this on your platform, does this happen 100% of the time? Can you add some logging for the |
I can reproduce this 100% of the time on my machine, yes. My setup: Installed modules:
To reproduce the issue for me, it's enough to run this: <?php
// composer require ratchet/pawl
require __DIR__ . '/vendor/autoload.php';
\Ratchet\Client\connect('wss://expose.dev/expose/control', [], [
'X-Expose-Control' => 'enabled'
])->then(function($conn) {
$conn->send(str_repeat('a', 1024*150));
}); This (without the fix) closes the connection 100% of the time. |
@clue the error handler does not get called, so nothing gets echoed for me |
@mpociot can you disable blackfire and try without the fix? |
@WyriHaximus that fails as well |
@mpociot ok good so it's not interfering 👍 |
I think you need fragmented TLS records to reproduce it. |
@kelunik that would make sense, since the |
Yes, except that writes fail, not reads. But with TLS any IO operations might require reads / writes, see WANT_WRITE and WANT_READ. We wanted to expose the last openssl error, but haven't done so, yet. |
Thanks for providing this reproduction script, this helped identify the underlying cause and I've just filed #150 as a more permanent fix without having to rely on retry behavior. Again thanks to @WyriHaximus and @mpociot for reporting and filing an initial work-around in here. I've had a chat earlier today with @mpociot to verify my assumption and we've been able to reproduce and fix this some minimal changes to the existing test suite and code base. I have intentionally pushed this as multiple commits to highlight this exact issue in #150. |
Spent a few hours helping @mpociot trace down a bug with his
expose
project. Now the bug he ran into boils down to afwrite
reporting 0 bytes written despite reporting itself as writable. Normally we would consider this stream closed at this point, but in some rare situationsfwrite
will return 0 because the stream isn't writable but is still open. Locally I couldn't reproduce it so I was kinda pulling my hair out. So to test some ideas I prepared a file with several possible fixes that could be the issue, included some debug output and send it to @mpociot.The red encircled output is the retry kicking in after it tried to write but it didn't.