Fix ConnectionErrorProof response count on single node read errors
on a read error, executeSingleNode() computed the number of missing responses from the already dequeued command queue, so it returned too few elements or threw a ValueError from array_fill(). the failed command and all remaining ones now get the connection exception, matching executeCluster().
This commit is contained in:
1 parent
7c87a97e67
commit
d75f5e786f
3 files changed
+58
-1
No files matched your search
@@ -13,6 +13,7 @@
|
|||||||
- Fixed `MultiExec::multi()` being ignored as the first call of a CAS transaction
|
- Fixed `MultiExec::multi()` being ignored as the first call of a CAS transaction
|
||||||
- Fixed cleanup of empty transactions and transaction callbacks that throw PHP errors
|
- Fixed cleanup of empty transactions and transaction callbacks that throw PHP errors
|
||||||
- Fixed `spl_object_hash()` deprecation on PHP 8.6 in `ConnectionErrorProof` pipeline
|
- Fixed `spl_object_hash()` deprecation on PHP 8.6 in `ConnectionErrorProof` pipeline
|
||||||
|
- Fixed `ConnectionErrorProof` pipeline returning too few responses or throwing `ValueError` on read errors with a single connection
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
- Fixed aborted cluster transactions leaving node connections in `MULTI`
|
- Fixed aborted cluster transactions leaving node connections in `MULTI`
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class ConnectionErrorProof extends Pipeline
|
|||||||
try {
|
try {
|
||||||
$responses[$i] = $connection->readResponse($command);
|
$responses[$i] = $connection->readResponse($command);
|
||||||
} catch (CommunicationException $exception) {
|
} catch (CommunicationException $exception) {
|
||||||
$add = count($commands) - count($responses);
|
$add = $sizeOfPipe - count($responses);
|
||||||
$responses = array_merge($responses, array_fill(0, $add, $exception));
|
$responses = array_merge($responses, array_fill(0, $add, $exception));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -138,6 +138,62 @@ class ConnectionErrorProofTest extends PredisTestCase
|
|||||||
$pipeline->execute();
|
$pipeline->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider singleConnectionReadFailureProvider
|
||||||
|
* @group disconnected
|
||||||
|
*/
|
||||||
|
public function testReturnsExceptionForFailedAndRemainingCommandsOnReadFailureWithSingleConnection(
|
||||||
|
int $sizeOfPipe,
|
||||||
|
int $failingIndex
|
||||||
|
): void {
|
||||||
|
$connection = $this->getMockConnection('tcp://127.0.0.1:7001');
|
||||||
|
$exception = new ConnectionException($connection, 'Connection lost');
|
||||||
|
|
||||||
|
$readResponses = [];
|
||||||
|
$expectedResponses = [];
|
||||||
|
|
||||||
|
for ($i = 0; $i < $sizeOfPipe; ++$i) {
|
||||||
|
if ($i < $failingIndex) {
|
||||||
|
$readResponses[] = "value$i";
|
||||||
|
$expectedResponses[] = "value$i";
|
||||||
|
} else {
|
||||||
|
$expectedResponses[] = $exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$readResponses[] = $this->throwException($exception);
|
||||||
|
|
||||||
|
$connection
|
||||||
|
->expects($this->once())
|
||||||
|
->method('write');
|
||||||
|
$connection
|
||||||
|
->expects($this->exactly($failingIndex + 1))
|
||||||
|
->method('readResponse')
|
||||||
|
->willReturnOnConsecutiveCalls(...$readResponses);
|
||||||
|
|
||||||
|
$pipeline = new ConnectionErrorProof(new Client($connection));
|
||||||
|
|
||||||
|
for ($i = 0; $i < $sizeOfPipe; ++$i) {
|
||||||
|
$pipeline->echo("value$i");
|
||||||
|
}
|
||||||
|
|
||||||
|
$responses = $pipeline->execute();
|
||||||
|
|
||||||
|
$this->assertCount($sizeOfPipe, $responses);
|
||||||
|
$this->assertSame($expectedResponses, $responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function singleConnectionReadFailureProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'single command' => [1, 0],
|
||||||
|
'first of three' => [3, 0],
|
||||||
|
'second of three' => [3, 1],
|
||||||
|
'last of three' => [3, 2],
|
||||||
|
'fourth of five' => [5, 3],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a mocked cluster connection routing commands by their first key.
|
* Returns a mocked cluster connection routing commands by their first key.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in new issue
Block a user