Merge branch 'refs/heads/topic-retain'

This commit is contained in:
Chris Boden 2014-06-07 11:25:27 -04:00
commit 0a501fef5d
3 changed files with 54 additions and 13 deletions

View File

@ -6,6 +6,13 @@ use Ratchet\ConnectionInterface;
* A topic/channel containing connections that have subscribed to it
*/
class Topic implements \IteratorAggregate, \Countable {
/**
* If true the TopicManager will destroy this object if it's ever empty of connections
* @deprecated in v0.4
* @type bool
*/
public $autoDelete = false;
private $id;
private $subscribers;

View File

@ -54,13 +54,12 @@ class TopicManager implements WsServerInterface, WampServerInterface {
public function onUnsubscribe(ConnectionInterface $conn, $topic) {
$topicObj = $this->getTopic($topic);
if ($conn->WAMP->subscriptions->contains($topicObj)) {
$conn->WAMP->subscriptions->detach($topicObj);
} else {
if (!$conn->WAMP->subscriptions->contains($topicObj)) {
return;
}
$this->topicLookup[$topic]->remove($conn);
$this->cleanTopic($topicObj, $conn);
$this->app->onUnsubscribe($conn, $topicObj);
}
@ -77,11 +76,8 @@ class TopicManager implements WsServerInterface, WampServerInterface {
public function onClose(ConnectionInterface $conn) {
$this->app->onClose($conn);
foreach ($this->topicLookup as $topic => $storage) {
$storage->remove($conn);
if (0 === $storage->count()) {
unset($this->topicLookup[$topic]);
}
foreach ($this->topicLookup as $topic) {
$this->cleanTopic($topic, $conn);
}
}
@ -114,4 +110,16 @@ class TopicManager implements WsServerInterface, WampServerInterface {
return $this->topicLookup[$topic];
}
protected function cleanTopic(Topic $topic, ConnectionInterface $conn) {
if ($conn->WAMP->subscriptions->contains($topic)) {
$conn->WAMP->subscriptions->detach($topic);
}
$this->topicLookup[$topic->getId()]->remove($conn);
if ($topic->autoDelete && 0 === $topic->count()) {
unset($this->topicLookup[$topic->getId()]);
}
}
}

View File

@ -159,9 +159,7 @@ class TopicManagerTest extends \PHPUnit_Framework_TestCase {
$this->mngr->onClose($this->conn);
}
public function testConnIsRemovedFromTopicOnClose() {
$name = 'State testing';
protected function topicProvider($name) {
$class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
$method = $class->getMethod('getTopic');
$method->setAccessible(true);
@ -171,14 +169,42 @@ class TopicManagerTest extends \PHPUnit_Framework_TestCase {
$topic = $method->invokeArgs($this->mngr, array($name));
return array($topic, $attribute);
}
public function testConnIsRemovedFromTopicOnClose() {
$name = 'State Testing';
list($topic, $attribute) = $this->topicProvider($name);
$this->assertCount(1, $attribute->getValue($this->mngr));
$this->mngr->onSubscribe($this->conn, $name);
$this->mngr->onClose($this->conn);
$this->assertFalse($topic->has($this->conn));
}
$this->assertCount(0, $attribute->getValue($this->mngr));
public static function topicConnExpectationProvider() {
return array(
array(true, 'onClose', 0)
, array(true, 'onUnsubscribe', 0)
, array(false, 'onClose', 1)
, array(false, 'onUnsubscribe', 1)
);
}
/**
* @dataProvider topicConnExpectationProvider
*/
public function testTopicRetentionFromLeavingConnections($autoDelete, $methodCall, $expectation) {
$topicName = 'checkTopic';
list($topic, $attribute) = $this->topicProvider($topicName);
$topic->autoDelete = $autoDelete;
$this->mngr->onSubscribe($this->conn, $topicName);
call_user_func_array(array($this->mngr, $methodCall), array($this->conn, $topicName));
$this->assertCount($expectation, $attribute->getValue($this->mngr));
}
public function testOnErrorBubbles() {