mirror of
https://github.com/predis/predis.git
synced 2026-09-13 11:57:02 +00:00
Make Predis\Network\MasterSlaveReplication serializable.
Since PHP cannot serialize closures we switched to a private method to check if a SORT command is a read-only operation, but closures are still supported even if they will make the connection unserializable.
This commit is contained in:
@@ -262,7 +262,7 @@ class MasterSlaveReplication implements IConnectionReplication
|
||||
return true;
|
||||
}
|
||||
|
||||
return $readonly($command);
|
||||
return call_user_func($readonly, $command);
|
||||
}
|
||||
|
||||
if (($eval = $id === 'EVAL') || $id === 'EVALSHA') {
|
||||
@@ -273,13 +273,23 @@ class MasterSlaveReplication implements IConnectionReplication
|
||||
return true;
|
||||
}
|
||||
|
||||
return $readonly($command);
|
||||
return call_user_func($readonly, $command);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a SORT command is a readable operation by parsing the arguments
|
||||
* array of the specified commad instance.
|
||||
*/
|
||||
private function isSortReadOnly(ICommand $command)
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
return ($c = count($arguments)) === 1 ? true : $arguments[$c - 2] !== 'STORE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a command as a read-only operation. When the behaviour of a
|
||||
* command can be decided only at runtime depending on its arguments,
|
||||
@@ -396,10 +406,15 @@ class MasterSlaveReplication implements IConnectionReplication
|
||||
'ECHO' => true,
|
||||
'QUIT' => true,
|
||||
'OBJECT' => true,
|
||||
'SORT' => function(ICommand $command) {
|
||||
$arguments = $command->getArguments();
|
||||
return ($c = count($arguments)) === 1 ? true : $arguments[$c - 2] !== 'STORE';
|
||||
},
|
||||
'SORT' => array($this, 'isSortReadOnly'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return array('master', 'slaves', 'disallowed', 'readonly', 'readonlySHA1');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,6 +410,29 @@ class MasterSlaveReplicationTest extends StandardTestCase
|
||||
$replication->executeCommand($cmdEval);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testSortTriggersSwitchToMasterConnectionOnStoreModifier()
|
||||
{
|
||||
$profile = ServerProfile::get('dev');
|
||||
$cmdSortNormal = $profile->createCommand('sort', array('key'));
|
||||
$cmdSortStore = $profile->createCommand('sort', array('key', array('store' => 'key:store')));
|
||||
|
||||
$master = $this->getMockConnection('tcp://host1?alias=master');
|
||||
$master->expects($this->once())->method('executeCommand')->with($cmdSortStore);
|
||||
|
||||
$slave1 = $this->getMockConnection('tcp://host2?alias=slave1');
|
||||
$slave1->expects($this->once())->method('executeCommand')->with($cmdSortNormal);
|
||||
|
||||
$replication = new MasterSlaveReplication();
|
||||
$replication->add($master);
|
||||
$replication->add($slave1);
|
||||
|
||||
$replication->executeCommand($cmdSortNormal);
|
||||
$replication->executeCommand($cmdSortStore);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
* @expectedException Predis\NotSupportedException
|
||||
@@ -508,6 +531,24 @@ class MasterSlaveReplicationTest extends StandardTestCase
|
||||
$replication->executeCommand($cmdEvalSha);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testCanBeSerialized()
|
||||
{
|
||||
$master = $this->getMockConnection('tcp://host1?alias=master');
|
||||
$slave1 = $this->getMockConnection('tcp://host2?alias=slave1');
|
||||
|
||||
$replication = new MasterSlaveReplication();
|
||||
$replication->add($master);
|
||||
$replication->add($slave1);
|
||||
|
||||
$unserialized = unserialize(serialize($replication));
|
||||
|
||||
$this->assertEquals($master, $unserialized->getConnectionById('master'));
|
||||
$this->assertEquals($slave1, $unserialized->getConnectionById('slave1'));
|
||||
}
|
||||
|
||||
// ******************************************************************** //
|
||||
// ---- HELPER METHODS ------------------------------------------------ //
|
||||
// ******************************************************************** //
|
||||
|
||||
Reference in New Issue
Block a user