function __construct($topic, Session $session, $options = null) { $this->topic = $topic; $this->session = $session; $this->options = new \stdClass(); $this->id = Session::getUniqueId(); }
public function testMakingCallIncrementsCallCount() { $mockSession = $this->getMockBuilder('\\Thruway\\Session')->setConstructorArgs([new \Thruway\Transport\DummyTransport()])->getMock(); $this->assertEquals(0, $this->_registration->getCurrentCallCount()); $callMsg = new \Thruway\Message\CallMessage(\Thruway\Session::getUniqueId(), new \stdClass(), 'test_procedure'); $call = new \Thruway\Call($mockSession, $callMsg); $this->_registration->processCall($call); $this->assertEquals(1, $this->_registration->getCurrentCallCount()); }
public function testQueueProcessAfterNonMultiYield() { $seq = 0; // there will be two callees //// Mocking $realm = $this->getMockBuilder('\\Thruway\\Realm')->setConstructorArgs(["theRealm"])->setMethods(["publishMeta"])->getMock(); $sessionMockBuilder = $this->getMockBuilder('\\Thruway\\Session')->setMethods(['sendMessage'])->disableOriginalConstructor(); $callee0Session = $sessionMockBuilder->getMock(); $callee1Session = $sessionMockBuilder->getMock(); $callerSession = $sessionMockBuilder->getMock(); $callee0Session->setRealm($realm); $callee1Session->setRealm($realm); $callerSession->setRealm($realm); //// End of Mocking $realm->expects($this->exactly(2))->method("publishMeta")->with($this->equalTo('thruway.metaevent.procedure.congestion'), $this->equalTo([["name" => "qpanmy_proc0"]])); $invocationIDs = []; $callee0Session->expects($this->exactly(6))->method("sendMessage")->withConsecutive([$this->isInstanceOf('\\Thruway\\Message\\RegisteredMessage')], [$this->callback(function ($value) use(&$invocationIDs) { $this->assertInstanceOf('\\Thruway\\Message\\InvocationMessage', $value); $invocationIDs[0] = $value->getRequestId(); return true; })], [$this->callback(function ($value) use(&$invocationIDs) { $this->assertInstanceOf('\\Thruway\\Message\\InvocationMessage', $value); $invocationIDs[1] = $value->getRequestId(); return true; })], [$this->isInstanceOf('\\Thruway\\Message\\RegisteredMessage')], [$this->callback(function ($value) use(&$invocationIDs) { $this->assertInstanceOf('\\Thruway\\Message\\InvocationMessage', $value); $invocationIDs[2] = $value->getRequestId(); return true; })], [$this->callback(function ($value) use(&$invocationIDs) { // invocation after yield $this->assertInstanceOf('\\Thruway\\Message\\InvocationMessage', $value); $invocationIDs[3] = $value->getRequestId(); return true; })]); // create a dealer $dealer = new \Thruway\Role\Dealer(); // register proc0 as multi $registerMsg = new \Thruway\Message\RegisterMessage(Session::getUniqueId(), ["thruway_multiregister" => true], "qpanmy_proc0"); $dealer->onMessage($callee0Session, $registerMsg); $callMsg = new \Thruway\Message\CallMessage(Session::getUniqueId(), [], "qpanmy_proc0"); $dealer->onMessage($callerSession, $callMsg); $callMsg->setRequestId(Session::getUniqueId()); $dealer->onMessage($callerSession, $callMsg); $dealer->onMessage($callee0Session, new \Thruway\Message\YieldMessage($invocationIDs[0], [])); $dealer->onMessage($callee0Session, new \Thruway\Message\YieldMessage($invocationIDs[1], [])); // there are now zero calls on proc0 $registerMsg = new \Thruway\Message\RegisterMessage(Session::getUniqueId(), [], "qpanmy_proc1"); $callProc1Msg = new \Thruway\Message\CallMessage(Session::getUniqueId(), [], "qpanmy_proc1"); $dealer->onMessage($callee0Session, $registerMsg); $dealer->onMessage($callerSession, $callProc1Msg); // this should cause congestion and queuing because it should be busy with proc1 $callMsg->setRequestId(Session::getUniqueId()); $dealer->onMessage($callerSession, $callMsg); // yield on proc1 - this should cause proc0 to process queue $dealer->onMessage($callee0Session, new \Thruway\Message\YieldMessage($invocationIDs[2], [])); }
/** * Constructor * * @param \Thruway\Session $callerSession * @param \Thruway\Message\CallMessage $callMessage * @param Registration $registration */ public function __construct(Session $callerSession, CallMessage $callMessage, Registration $registration = null) { $this->callMessage = $callMessage; $this->callerSession = $callerSession; $this->invocationMessage = null; $this->calleeSession = null; $this->isProgressive = false; $this->setRegistration($registration); $this->callStart = microtime(true); $this->invocationRequestId = Session::getUniqueId(); }
/** * Constructor * * @param \Thruway\Transport\TransportInterface $transport * @param \Thruway\Manager\ManagerInterface $manager */ public function __construct(TransportInterface $transport, ManagerInterface $manager = null) { $this->transport = $transport; $this->state = static::STATE_PRE_HELLO; $this->sessionId = Session::getUniqueId(); $this->realm = null; $this->messagesSent = 0; $this->sessionStart = new \DateTime(); $this->authenticationDetails = null; $this->pendingCallCount = 0; if ($manager === null) { $manager = new ManagerDummy(); } $this->setManager($manager); }
/** * Constructor * * @param \Thruway\Session $session * @param string $procedureName */ public function __construct(Session $session, $procedureName) { $this->id = Session::getUniqueId(); $this->session = $session; $this->procedureName = $procedureName; $this->allowMultipleRegistrations = false; $this->discloseCaller = false; $this->calls = []; $this->registeredAt = new \DateTime(); $this->invocationCount = 0; $this->busyTime = 0; $this->invocationAverageTime = 0; $this->maxSimultaneousCalls = 0; $this->lastCallStartedAt = null; $this->lastIdledAt = $this->registeredAt; $this->busyStart = null; $this->completedCallTimeTotal = 0; }
public function testDoNotExcludeMe() { $transport = $this->getMockBuilder('\\Thruway\\Transport\\TransportInterface')->getMock(); $transport->expects($this->any())->method("getTransportDetails")->will($this->returnValue("")); $session = $this->getMockBuilder('\\Thruway\\Session')->setMethods(["sendMessage"])->setConstructorArgs([$transport])->getMock(); $broker = new \Thruway\Role\Broker(); $subscribeMsg = new \Thruway\Message\SubscribeMessage('\\Thruway\\Session', [], "test_subscription"); /** @var \Thruway\Message\SubscribedMessage $subscribedMsg */ $subscribedMsg = null; $session->expects($this->exactly(3))->method("sendMessage")->withConsecutive([$this->callback(function ($msg) use(&$subscribedMsg) { $this->isInstanceOf('\\Thruway\\Message\\SubscribedMessage'); $subscribedMsg = $msg; return true; })], [$this->isInstanceOf('\\Thruway\\Message\\PublishedMessage')], [$this->isInstanceOf('\\Thruway\\Message\\EventMessage')]); $broker->onMessage($session, $subscribeMsg); $subscriptionId = $subscribedMsg->getSubscriptionId(); $publishMsg = new \Thruway\Message\PublishMessage(\Thruway\Session::getUniqueId(), ['exclude_me' => false, 'acknowledge' => true], 'test_subscription'); $broker->onMessage($session, $publishMsg); }
/** * Process publish message * * @param \Thruway\Session $session * @param \Thruway\Message\PublishMessage $msg */ protected function processPublish(Session $session, PublishMessage $msg) { Logger::debug($this, "processing publish message"); $includePublisher = false; $excludedSessions = []; $whiteList = null; $options = $msg->getOptions(); if (is_array($options)) { // see if they wanted confirmation if (isset($options['acknowledge']) && $options['acknowledge'] == true) { $publicationId = Session::getUniqueId(); $session->sendMessage(new PublishedMessage($msg->getRequestId(), $publicationId)); } if (isset($options['exclude_me']) && !$options['exclude_me']) { $includePublisher = true; } if (isset($options['exclude']) && is_array($options['exclude'])) { // fixup exclude array - make sure it is legit foreach ($options['exclude'] as $excludedSession) { if (is_numeric($excludedSession)) { array_push($excludedSessions, $excludedSession); } } } if (isset($options['eligible']) && is_array($options['eligible'])) { $whiteList = []; foreach ($options['eligible'] as $sessionId) { if (is_numeric($sessionId)) { array_push($whiteList, $sessionId); } } } } /* @var $subscription \Thruway\Subscription */ foreach ($this->subscriptions as $subscription) { if ($msg->getTopicName() == $subscription->getTopic() && ($includePublisher || $subscription->getSession() != $session)) { if (!in_array($subscription->getSession()->getSessionId(), $excludedSessions)) { if ($whiteList === null || in_array($subscription->getSession()->getSessionId(), $whiteList)) { $eventMsg = EventMessage::createFromPublishMessage($msg, $subscription->getId()); $this->disclosePublisherOption($session, $eventMsg, $subscription); $subscription->getSession()->sendMessage($eventMsg); } } } } }
/** * Publish meta * * @param string $topicName * @param mixed $arguments * @param mixed $argumentsKw * @param mixed $options */ public function publishMeta($topicName, $arguments, $argumentsKw = null, $options = null) { if ($this->metaSession === null) { // setup a new metaSession $s = new Session(new DummyTransport()); $this->metaSession = $s; } $this->getBroker()->onMessage($this->metaSession, new PublishMessage(Session::getUniqueId(), $options, $topicName, $arguments, $argumentsKw)); }
/** * process publish * * @param \Thruway\ClientSession $session * @param string $topicName * @param mixed $arguments * @param mixed $argumentsKw * @param mixed $options * @return \React\Promise\Promise */ public function publish(ClientSession $session, $topicName, $arguments, $argumentsKw, $options) { $requestId = Session::getUniqueId(); if (isset($options['acknowledge']) && $options['acknowledge'] === true) { $futureResult = new Deferred(); $this->publishRequests[$requestId] = ['future_result' => $futureResult]; } $publishMsg = new PublishMessage($requestId, $options, $topicName, $arguments, $argumentsKw); $session->sendMessage($publishMsg); return isset($futureResult) ? $futureResult->promise() : false; }
/** * process subscribe * * @param \Thruway\ClientSession $session * @param string $topicName * @param callable $callback * @param $options * @return Promise */ public function subscribe(ClientSession $session, $topicName, $callback, $options) { $requestId = Session::getUniqueId(); $options = (object) $options; $deferred = new Deferred(); $subscription = ["topic_name" => $topicName, "callback" => $callback, "request_id" => $requestId, "options" => $options, "deferred" => $deferred]; array_push($this->subscriptions, $subscription); $subscribeMsg = new SubscribeMessage($requestId, $options, $topicName); $session->sendMessage($subscribeMsg); return $deferred->promise(); }
public function testCallBeforeWelcome() { $realm = new \Thruway\Realm("realm1"); $session = $this->getMockBuilder('\\Thruway\\Session')->disableOriginalConstructor()->setMethods(["sendMessage", "shutdown", "abort"])->getMock(); $session->expects($this->once())->method("abort")->with($this->isInstanceOf("stdClass"), $this->equalTo("wamp.error.not_authorized")); $realm->onMessage($session, new \Thruway\Message\CallMessage(\Thruway\Session::getUniqueId(), [], 'some_procedure')); }
/** * process call * * @param \Thruway\ClientSession $session * @param string $procedureName * @param mixed $arguments * @param mixed $argumentsKw * @param mixed $options * @return \React\Promise\Promise */ public function call(ClientSession $session, $procedureName, $arguments = null, $argumentsKw = null, $options = null) { //This promise gets resolved in Caller::processResult $futureResult = new Deferred(); $requestId = Session::getUniqueId(); $this->callRequests[$requestId] = ["procedure_name" => $procedureName, "future_result" => $futureResult]; if (!(is_array($options) && Message::isAssoc($options))) { if ($options !== null) { Logger::warning($this, "Options don't appear to be the correct type."); } $options = new \stdClass(); } $callMsg = new CallMessage($requestId, $options, $procedureName, $arguments, $argumentsKw); $session->sendMessage($callMsg); return $futureResult->promise(); }
/** * @param Session $session * @param PublishMessage $msg */ public function processPublish(Session $session, PublishMessage $msg) { $this->manager->debug("processing publish message"); $receivers = isset($this->topics[$msg->getTopicName()]) ? $this->topics[$msg->getTopicName()] : null; //If the topic doesn't have any subscribers if (empty($receivers)) { $receivers = array(); } // see if they wanted confirmation $options = $msg->getOptions(); if (is_array($options)) { if (isset($options['acknowledge']) && $options['acknowledge'] == true) { $publicationId = Session::getUniqueId(); $session->sendMessage(new PublishedMessage($msg->getRequestId(), $publicationId)); } } $eventMsg = EventMessage::createFromPublishMessage($msg); /* @var $receiver Session */ foreach ($receivers as $receiver) { if ($receiver != $session) { $receiver->sendMessage($eventMsg); } } }
/** * @param $topicName * @param $callback */ public function subscribe(ClientSession $session, $topicName, $callback) { $requestId = Session::getUniqueId(); $options = new \stdClass(); $subscription = ["topic_name" => $topicName, "callback" => $callback, "request_id" => $requestId, "options" => $options]; array_push($this->subscriptions, $subscription); $subscribeMsg = new SubscribeMessage($requestId, $options, $topicName); $session->sendMessage($subscribeMsg); }
/** * @param CallMessage $msg * @param Registration $registration * @return static */ static function createMessageFrom(CallMessage $msg, Registration $registration) { $requestId = Session::getUniqueId(); $details = new \stdClass(); return new static($requestId, $registration->getId(), $details, $msg->getArguments(), $msg->getArgumentsKw()); }
public function testLeave() { $session = $this->getMockBuilder('\\Thruway\\Session')->disableOriginalConstructor()->getMock(); $session->expects($this->once())->method("sendMessage")->with($this->isInstanceOf('\\Thruway\\Message\\RegisteredMessage')); $registerMsg = new \Thruway\Message\RegisterMessage(\Thruway\Session::getUniqueId(), [], 'test_procedure'); $this->_proc->processRegister($session, $registerMsg); $this->assertEquals(1, count($this->_proc->getRegistrations())); $this->_proc->leave($session); $this->assertEquals(0, count($this->_proc->getRegistrations())); }
/** * process unregister * * @param \Thruway\ClientSession $session * @param string $Uri * @throws \Exception * @return \React\Promise\Promise|false */ public function unregister(ClientSession $session, $Uri) { // TODO: maybe add an option to wait for pending calls to finish $registration = null; foreach ($this->registrations as $k => $r) { if (isset($r['procedure_name'])) { if ($r['procedure_name'] == $Uri) { $registration =& $this->registrations[$k]; break; } } } if ($registration === null) { Logger::warning($this, "registration not found: " . $Uri); return false; } // we remove the callback from the client here // because we don't want the client to respond to any more calls $registration['callback'] = null; $futureResult = new Deferred(); if (!isset($registration["registration_id"])) { // this would happen if the registration was never acknowledged by the router // we should remove the registration and resolve any pending deferreds Logger::error($this, "Registration ID is not set while attempting to unregister " . $Uri); // reject the pending registration $registration['futureResult']->reject(); // TODO: need to figure out what to do in this off chance // We should still probably return a promise here that just rejects // there is an issue with the pending registration too that // the router may have a "REGISTERED" in transit and may still think that is // good to go - so maybe still send the unregister? } $requestId = Session::getUniqueId(); // save the request id so we can find this in the registration // list to call the deferred and remove it from the list $registration['unregister_request_id'] = $requestId; $registration['unregister_deferred'] = $futureResult; $unregisterMsg = new UnregisterMessage($requestId, $registration['registration_id']); $session->sendMessage($unregisterMsg); return $futureResult->promise(); }
/** * @param $procedureName * @param $arguments * @return \React\Promise\Promise */ public function call(ClientSession $session, $procedureName, $arguments = null, $argumentsKw = null) { //This promise gets resolved in Caller::processResult $futureResult = new Deferred(); $requestId = Session::getUniqueId(); $this->callRequests[$requestId] = ["procedure_name" => $procedureName, "future_result" => $futureResult]; $options = new \stdClass(); $callMsg = new CallMessage($requestId, $options, $procedureName, $arguments, $argumentsKw); $session->sendMessage($callMsg); return $futureResult->promise(); }