Skip to content

Retry connection on socket error #106

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

Merged
merged 4 commits into from
Dec 10, 2017
Merged

Retry connection on socket error #106

merged 4 commits into from
Dec 10, 2017

Conversation

cebe
Copy link
Member

@cebe cebe commented Apr 4, 2017

Possible solution for #91.

currently does not handle fwrite failure, only socket read.

@cebe
Copy link
Member Author

cebe commented Apr 4, 2017

related to #57 and yiisoft/yii2#6356

Connection.php Outdated
while ($retries-- >= 0) {
try {
fwrite($this->_socket, $command);
return $this->parseResponse(implode(' ', $params));
Copy link
Member

Choose a reason for hiding this comment

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

Should $this->retries be reset here on success?

Copy link
Member Author

Choose a reason for hiding this comment

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

it has not changed, I call -- on $retries only.

Copy link
Member

Choose a reason for hiding this comment

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

I mean currently $retries is shared among all queries and I think it should be per query.

Copy link
Member Author

@cebe cebe Apr 5, 2017

Choose a reason for hiding this comment

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

it is per query currently. One call to "executeCommand" is one query.

Copy link
Member

Choose a reason for hiding this comment

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

Good morning myself :( I was looking at $retries-- seeing $this->retries--. Sorry.

Connection.php Outdated
@@ -647,8 +653,20 @@ public function executeCommand($name, $params = [])
}

\Yii::trace("Executing Redis Command: {$name}", __METHOD__);
if ($this->retries > 0) {

Choose a reason for hiding this comment

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

$tries = $this->retries + 1;
while ($tries--) {
    try {
    } catch () {
    }
}

This might be better, and also removed the duplicated codes (fwrite and parseResp)

Copy link
Member Author

Choose a reason for hiding this comment

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

looks better code wise, but it has the problem, that even if retry is disabled, the connection is reset on the first error.

@cebe cebe requested review from samdark, SilverFire and a team December 5, 2017 14:59
@cebe cebe changed the title WIP retry connection on socket error Retry connection on socket error Dec 5, 2017
$db = $this->getConnection(false);
$db->configSet('timeout', 1);
$this->assertTrue($db->ping());
sleep(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if these tests pass, since you have a timeout of 1 (sec?) and you sleep 1 seconds, plus a few microseconds for code-execution... Wouldn't it be better to lower this to 0.5?

Copy link
Member Author

Choose a reason for hiding this comment

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

We could change it if needed but I have not seen any issues with this, neither locally nor on travis. Will improve tests a bit.

sleep(1);
$this->assertTrue($db->ping());
sleep(2);
$this->assertTrue($db->ping());
Copy link
Contributor

Choose a reason for hiding this comment

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

I would add another two lines with sleep(3) and the expected exception from above.

Copy link
Member

@sergeymakinen sergeymakinen left a comment

Choose a reason for hiding this comment

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

I have not reviewed tests in detail but the implementation LGTM.

Connection.php Outdated
fwrite($this->_socket, $command);
if ($this->retries > 0) {
$tries = $this->retries;
while ($tries-- >= 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks incorrect. If $tries = 1 then $tries-- will return 1. So $this->retries = 1 will result 2 retries instead of 1.

It should be while ($tries-- > 0) or use pre-increment.

Copy link
Member Author

Choose a reason for hiding this comment

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

if $tries = 1, the while loop will run once. that means on first exception, it will try to reconnect, then not enter the while loop again so the second command will run normally. This will be 2 "tries" but one of them is the retry ;)

Imo that is correct and expected. $this->retries = 0 means one command execution, $this->retries = 1 means two in case of error.

Copy link
Contributor

Choose a reason for hiding this comment

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

if $tries = 1, the while loop will run once.

It will run twice: https://3v4l.org/NObVY

Or I'm missing something obvious. :P

Copy link
Contributor

Choose a reason for hiding this comment

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

while (--$tries >= 0) {
    $i++;
}

Runs once 🤓

https://3v4l.org/UhA6J

Copy link
Member Author

Choose a reason for hiding this comment

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

Seems I mixed up the combination of -- before or after and the > and >= usage.

  • --$tries decrements first and then checks against 0
  • $tries-- checks against 0 and then decrements

Will add a test to verify the number of trials.

Copy link
Member

Choose a reason for hiding this comment

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

I'd make that explicit by separating decrement and condition.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed.

@samdark
Copy link
Member

samdark commented Dec 6, 2017

Travis fails.

@cebe
Copy link
Member Author

cebe commented Dec 6, 2017

Oh, that was because I rebased on master. Tests for this PR are passing.

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.

6 participants