/** * Run the controller. Dequeues signals from the SW Engine's internal queue and * notifies the listeners that a signal from SW Engine has been received * * @return void */ public function run() { $timeout = $this->_options[self::OPT_TIMEOUT]; Streamwide_Engine_Logger::info('Going to main loop'); for (;;) { // Fetch a new signal from the SW Engine's queue $signal = Streamwide_Engine_Signal::dequeue(array('timeout' => $timeout)); if (false === $signal) { continue; } // Update the loggers event items Streamwide_Engine_Logger::updateLogEventItems(array($signal->getPhpId() => $signal->getParams())); // Log the received signal Streamwide_Engine_Logger::dump($signal->toArray(), 'Received event from SW Engine:'); if ($signal->getName() === Streamwide_Engine_Signal::CREATE) { // We have received a CREATE (new call), we need to create a new application to handle // the call if (false === ($application = $this->_createNewApplication($signal))) { continue; } // Add the new application to the controller's running apps storage (will call // the application's start method) $this->addApp($signal->getPhpId(), $application); } else { // We have received a signal from SW Engine, we need to notify the listeners $event = new Streamwide_Engine_Events_Event($signal->getName()); $event->setParam('signal', $signal); $this->dispatchEvent($event); } } }
/** * Sends a signal to SW Engine * * @param integer $retries If as_send_event returns false, we can retry to send the signal * @return boolean */ public function send($retries = 0) { if (!is_int($retries)) { $retries = (int) $retries; } $array = $this->toArray(); do { Streamwide_Engine_Logger::dump($array, 'Sending to SW Engine:'); $sent = $this->_engineProxy->sendEvent($array); Streamwide_Engine_Logger::info(sprintf('Signal "%s" %s sent to SW Engine', $array[self::SIG_NAME], $sent === true ? 'successfully' : 'unsuccessfully')); $retries--; } while (false === $sent && $retries > 0); return $sent; }
/** * Dispatches an event. This means notifying all listeners and passing them the event object * * @param Streamwide_Event_Interface $event * @param scalar $phpId * @return void */ protected function _dispatchEvent(Streamwide_Event_Interface $event, $phpId) { $eventType = $event->getEventType(); $logMessage = 'Preparing to dispatch the "%s" event in phpId "%d" from event dispatcher of class "%s"'; Streamwide_Engine_Logger::info(sprintf($logMessage, $eventType, $phpId, $this->_class)); $logMessage = 'The event listeners count for class "%s" is %d'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $this->_class, $this->_count)); // search the event listener list for info that matches the php id and event type if (!isset($this->_list[$phpId][$eventType])) { $logMessage = 'Event "%s" will not be dispatched in phpId "%d" from event dispatcher of class "%s"'; $logMessage .= ' because no event listeners subscribed to it'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $eventType, $phpId, $this->_class)); return; } // If the event does not have a source yet, set the source to be the instance of this class, // this is needed because event dispatching capabilities can be aquired through composition too, // not only through inheritance if (null === $event->getEventSource()) { $event->setEventSource($this); } foreach (new ArrayIterator($this->_list[$phpId][$eventType]) as $offset => $listener) { if (!$event->isDispatchable()) { $logMessage = 'Breaking out of the event dispatching loop in phpId "%d" from event dispatcher of class "%s"'; $logMessage .= ' because the event object has been marked as undispatchable'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $phpId, $this->_class)); break; } if (!isset($this->_list[$phpId][$eventType][$offset])) { $forceExecution = $listener->getForceExecution(); if ($forceExecution) { $logMessage = 'Forcing execution of listener "%s" from "%s"'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $listener->getLoggingName(), $this->_class)); } else { $logMessage = 'Could not find offset "%d" in the event listener list in class "%s" while dispatching event "%s"'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $offset, $this->_class, $eventType)); continue; } } $specification = $listener->getNotifyFilter(); if (!$specification->isSatisfiedBy($event)) { $logMessage = 'Event "%s" will not be dispatched in phpId "%d" from event dispatcher of class "%s"'; $logMessage .= ' because the event does not satisfy the listener\'s specifications'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $eventType, $phpId, $this->_class)); continue; } if ($listener->isAutoRemovableBeforeExecution()) { $removeGroup = $listener->getRemoveGroup(); if ($removeGroup && null !== ($groupName = $listener->getGroup())) { $this->_flushByGroup($groupName); } else { unset($this->_list[$phpId][$eventType][$offset]); $this->_count--; $logMessage = 'Listener "%s" was automatically removed before execution from "%s"'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $listener->getLoggingName(), $this->_class)); $logMessage = 'The event listeners count for class "%s" is %d'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $this->_class, $this->_count)); } } // execute the listener $listener->execute($event); if ($listener->isAutoRemovableAfterExecution()) { $removeGroup = $listener->getRemoveGroup(); if ($removeGroup && null !== ($groupName = $listener->getGroup())) { $this->_flushByGroup($groupName); } else { unset($this->_list[$phpId][$eventType][$offset]); $this->_count--; $logMessage = 'Listener "%s" was automatically removed after execution from "%s"'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $listener->getLoggingName(), $this->_class)); $logMessage = 'The event listeners count for class "%s" is %d'; Streamwide_Engine_Logger::debug(sprintf($logMessage, $this->_class, $this->_count)); } } } if (isset($this->_list[$phpId][$eventType])) { $this->_performListMaintenance($phpId, $eventType); } }
/** * Execute the action that was attached to a certain event * * @param Streamwide_Event_Interface $event * @return mixed */ public function execute(Streamwide_Event_Interface $event = null) { Streamwide_Engine_Logger::info(sprintf('Executing callback "%s"', $this->_loggingName)); $args = $this->_args; $args[] = null === $event ? $this->_event : $event; return call_user_func_array($this->_callback, $args); }