application/hub/exceptions/lists/class_InvalidListHashException.php svneol=native#text/plain
application/hub/exceptions/lists/class_ListGroupAlreadyAddedException.php svneol=native#text/plain
application/hub/exceptions/lists/class_NoListGroupException.php svneol=native#text/plain
+application/hub/exceptions/package/.htaccess -text svneol=unset#text/plain
+application/hub/exceptions/package/class_UnexpectedPackageStatusException.php -text
application/hub/exceptions/peer/.htaccess -text svneol=unset#text/plain
application/hub/exceptions/peer/class_PeerAlreadyRegisteredException.php svneol=native#text/plain
application/hub/exceptions/resolver/.htaccess svneol=native#text/plain
application/hub/main/queues/peer/.htaccess -text svneol=unset#text/plain
application/hub/main/queues/peer/class_LocalPeerQueue.php svneol=native#text/plain
application/hub/main/registry/.htaccess -text svneol=unset#text/plain
+application/hub/main/registry/connection/.htaccess -text svneol=unset#text/plain
+application/hub/main/registry/connection/class_ConnectionRegistry.php svneol=native#text/plain
application/hub/main/registry/objects/.htaccess -text svneol=unset#text/plain
application/hub/main/registry/objects/class_ObjectTypeRegistry.php svneol=native#text/plain
application/hub/main/registry/socket/.htaccess -text svneol=unset#text/plain
application/hub/main/states/peer/errors/.htaccess -text svneol=unset#text/plain
application/hub/main/states/peer/errors/class_ConnectionRefusedPeerState.php svneol=native#text/plain
application/hub/main/states/peer/errors/class_ConnectionTimedOutPeerState.php svneol=native#text/plain
+application/hub/main/states/peer/errors/class_NoRouteToHostPeerState.php svneol=native#text/plain
+application/hub/main/states/peer/errors/class_OperationAlreadyProgressPeerState.php svneol=native#text/plain
+application/hub/main/states/peer/errors/class_TransportEndpointGonePeerState.php svneol=native#text/plain
application/hub/main/states/peer/init/.htaccess -text svneol=unset#text/plain
application/hub/main/states/peer/init/class_InitPeerState.php svneol=native#text/plain
application/hub/main/states/peer/new/.htaccess -text svneol=unset#text/plain
application/hub/main/visitor/pool/shutdown/.htaccess -text svneol=unset#text/plain
application/hub/main/visitor/pool/shutdown/class_ShutdownListenerPoolVisitor.php svneol=native#text/plain
application/hub/main/visitor/socket/.htaccess -text svneol=unset#text/plain
+application/hub/main/visitor/socket/class_HalfShutdownSocketVisitor.php svneol=native#text/plain
application/hub/main/visitor/socket/class_ShutdownSocketVisitor.php svneol=native#text/plain
application/hub/main/visitor/tasks/.htaccess -text svneol=unset#text/plain
application/hub/main/visitor/tasks/class_ActiveTaskVisitor.php svneol=native#text/plain
// CFG: SHUTDOWN-SOCKET-VISITOR-CLASS
$cfg->setConfigEntry('shutdown_socket_visitor_class', 'ShutdownSocketVisitor');
+// CFG: HALF-SHUTDOWN-SOCKET-VISITOR-CLASS
+$cfg->setConfigEntry('half_shutdown_socket_visitor_class', 'HalfShutdownSocketVisitor');
+
// CFG: ACTIVE-TASK-VISITOR-CLASS
$cfg->setConfigEntry('active_task_visitor_class', 'ActiveTaskVisitor');
$cfg->setConfigEntry('udp_buffer_length', 1024);
// CFG: TCP-CONNECT-RETRY-MAX
-$cfg->setConfigEntry('tcp_connect_retry_max', 10);
+$cfg->setConfigEntry('tcp_connect_retry_max', 5);
// CFG: UDP-CONNECT-RETRY-MAX
-$cfg->setConfigEntry('udp_connect_retry_max', 10);
+$cfg->setConfigEntry('udp_connect_retry_max', 5);
// CFG: NODE-STATE-CHECKED-PACKAGE-CLASS
$cfg->setConfigEntry('node_state_checked_package_class', 'NewConnectionNodeState');
// CFG: DEBUG-OUTPUT-TIMINGS
$cfg->setConfigEntry('debug_output_timings', 'Y');
+// CFG: SOCKET-TIMEOUT-SECONDS
+$cfg->setConfigEntry('socket_timeout_seconds', 3);
+
+// CFG: SOCKET-TIMEOUT-MICROSECONDS
+$cfg->setConfigEntry('socket_timeout_microseconds', 0);
+
///////////////////////////////////////////////////////////////////////////////
// Peer states
///////////////////////////////////////////////////////////////////////////////
// CFG: PEER-TRANSPORT-ENDPOINT-STATE-CLASS
$cfg->setConfigEntry('peer_transport_endpoint_state_class', 'TransportEndpointGonePeerState');
+// CFG: PEER-OPERATION-ALREADY-PROGRESS-STATE-CLASS
+$cfg->setConfigEntry('peer_operation_already_progress_state_class', 'OperationAlreadyProgressPeerState');
+
+// CFG: PEER-NO-ROUTE-TO-HOST-STATE-CLASS
+$cfg->setConfigEntry('peer_no_route_to_host_state_class', 'NoRouteToHostPeerState');
+
///////////////////////////////////////////////////////////////////////////////
// Cruncher configuration
///////////////////////////////////////////////////////////////////////////////
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * This exception is thrown when an unexpected package status was detected.
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class UnexpectedPackageStatusException extends FrameworkException {
+ /**
+ * The super constructor for all exceptions
+ *
+ * @param $messageArray Error message array
+ * @param $code Error code
+ * @return void
+ */
+ public function __construct (array $messageArray, $code) {
+ // Construct the message
+ $message = sprintf("[%s:%d] Unexpected package status %s!=%s detected, recipient=%s, sender=%s.",
+ $messageArray[0]->__toString(),
+ $this->getLine(),
+ $messageArray[1][NetworkPackage::PACKAGE_DATA_STATUS],
+ $messageArray[2],
+ $messageArray[1][NetworkPackage::PACKAGE_DATA_RECIPIENT],
+ $messageArray[1][NetworkPackage::PACKAGE_DATA_SENDER]
+ );
+
+ // Call parent exception constructor
+ parent::__construct($message, $code);
+ }
+}
+
+// [EOF]
+?>
* @return $iteratorInstance An instance of a Iterateable object
*/
function getIterator ();
+
+ /**
+ * Clears all recipients for e.g. another package to deliver
+ *
+ * @return void
+ */
+ function clearRecipients ();
}
// [EOF]
* @return $iteratorInstance An instance of a Iterator class
*/
function getListIterator ();
+
+ /**
+ * Clears this list (mostly by clearing all groups together)
+ *
+ * @return void
+ */
+ function clearList ();
}
// [EOF]
case 0: // Silently ignored, the socket is connected
break;
+ case 11: // "Resource temporary unavailable"
+ $errorName = BaseRawDataHandler::SOCKET_ERROR_RESOURCE_UNAVAILABLE;
+ break;
+
case 107: // "Transport end-point not connected"
case 134: // On some (?) systems for 'transport end-point not connected'
// @TODO On some systems it is 134, on some 107?
$errorName = BaseRawDataHandler::SOCKET_ERROR_CONNECTION_REFUSED;
break;
+ case 113: // "No route to host"
+ $errorName = BaseRawDataHandler::SOCKET_ERROR_NO_ROUTE_TO_HOST;
+ break;
+
+ case 114: // "Operation already in progress"
+ $errorName = BaseRawDataHandler::SOCKET_ERROR_OPERATION_ALREADY_PROGRESS;
+ break;
+
+ case 115: // "Operation now in progress"
+ $errorName = BaseRawDataHandler::SOCKET_ERROR_OPERATION_IN_PROGRESS;
+ break;
+
default: // Everything else <> 0
// Unhandled error code detected, so first debug it because we may want to handle it like the others
$this->debugOutput('[' . __METHOD__ . ':' . __LINE__ . '] UNKNOWN ERROR CODE = ' . $errorCode . ', MESSAGE = ' . socket_strerror($errorCode));
$this->accept($visitorInstance);
}
+ /**
+ * Half-shuts down a given socket resource. This method does only ease calling
+ * an other visitor than shutdownSocket() does.
+ *
+ * @param $socketResource A valid socket resource
+ * @return void
+ */
+ public function halfShutdownSocket ($socketResource) {
+ // Debug message
+ $this->debugOutput('HUB-SYSTEM: Half-shutting down socket resource ' . $socketResource . ' with state ' . $this->getPrintableState() . ' ...');
+
+ // Set socket resource
+ $this->setSocketResource($socketResource);
+
+ // Get a visitor instance
+ $visitorInstance = ObjectFactory::createObjectByConfiguredName('half_shutdown_socket_visitor_class');
+
+ // Call the visitor
+ $this->accept($visitorInstance);
+ }
+
/**
* "Getter" for a printable state name
*
// Output debug message
$discoveryInstance->debugOutput('RECIPIENT-DISCOVERY: Initialized.');
+ // Get recipients list instance and set it
+ $listInstance = RecipientListFactory::createRecipientListInstance();
+ $discoveryInstance->setListInstance($listInstance);
+
// Return the prepared instance
return $discoveryInstance;
}
* @return void
*/
public function discoverRecipients (array $packageData) {
- // Get recipients list instance
- $listInstance = RecipientListFactory::createRecipientListInstance();
-
// We do some rudimentary checks but this might be a bit ugly
switch ($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]) {
// All upper hubs, these are currently the bootstrap nodes and later on prepended list-nodes
/* DEBUG: */ $this->debugOutput('DISCOVERY: Adding node ' . $node . ' as recipient.');
// Add the entry
- $listInstance->addEntry('ip_port', $node);
+ $this->getListInstance()->addEntry('ip_port', $node);
} // END - foreach
break;
$ipPort = $ip . ':' . $this->getConfigInstance()->getConfigEntry('node_' . $this->determineProtocolByPackageData($packageData) . '_listen_port');
// Add it to the list
- $listInstance->addEntry('ip_port', $ipPort);
+ $this->getListInstance()->addEntry('ip_port', $ipPort);
break;
// This may be a direct recipient (node's session id)
* @return $iteratorInstance An instance of a Iterateable object
*/
public function getIterator () {
- // Get list instance
- $listInstance = RecipientListFactory::createRecipientListInstance();
-
// Get iterator from it
- $iteratorInstance = $listInstance->getIterator();
+ $iteratorInstance = $this->getListInstance()->getIterator();
// Return it
return $iteratorInstance;
}
+
+ /**
+ * Clears all recipients for e.g. another package to deliver. This method
+ * simply clears the inner list instance.
+ *
+ * @return void
+ */
+ public function clearRecipients () {
+ // Clear the list
+ $this->getListInstance()->clearList();
+ }
}
// [EOF]
$socketResource = $listenerInstance->getPoolInstance()->getSocketFromPackageData($packageData);
// Is it false, the recipient isn't known to us and we have no connection to it
- if ((!is_resource($socketResource)) || (socket_last_error($socketResource) > 0)) {
+ if (($socketResource === false) || (!is_resource($socketResource)) || (socket_last_error($socketResource) > 0)) {
// Try to create a new socket resource
try {
// Possibly noisy debug message
}
} // END - if
- // Get the helper instance from registry
- $helperInstance = Registry::getRegistry()->getInstance('connection');
+ // Try to resolve the socket resource
+ try {
+ // Get the helper instance from registry
+ $helperInstance = Registry::getRegistry()->getInstance('connection');
- // Possibly noisy debug message
- /* NOISY-DEBUG: */ $this->debugOutput('SOCKET-DISCOVERY: Going to resolve state by given package data ...');
+ // Possibly noisy debug message
+ /* NOISY-DEBUG: */ $this->debugOutput('SOCKET-DISCOVERY: Going to resolve socket from peer state and given package data ...');
- // Resolve the peer's state (but ignore return value)
- PeerStateResolver::resolveStateByPackage($helperInstance, $packageData, $socketResource);
+ // Resolve the peer's state (but ignore return value)
+ PeerStateResolver::resolveStateByPackage($helperInstance, $packageData, $socketResource);
+ } catch (InvalidSocketException $e) {
+ // This cannot be fixed, so log it away
+ $this->debugOutput('SOCKET-DISCOVERY: Cannot discover socket resource for recipient ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ': ' . $e->getMessage());
+
+ // Make any failed attempts to 'false'
+ $socketResource = false;
+ }
// And return it
return $socketResource;
* @return $socketResource Socket resource
*/
public static function createSocketFromPackageData (array $packageData, $protocolName) {
+ // Get an instance
+ $factoryInstance = new SocketFactory();
+
// Construct registry key
$registryKey = 'socket_' . $protocolName . '_' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT];
+ // Debug message
+ $factoryInstance->debugOutput('SOCKET-FACTORY: Trying to find a socket with registryKey=' . $registryKey);
+
// Is the key there?
if (Registry::getRegistry()->instanceExists($registryKey)) {
// Get container instance
// Get socket back
$socketResource = $containerInstance->getSocketResource();
+
+ // Debug message
+ $factoryInstance->debugOutput('SOCKET-FACTORY: Using socket ' . $socketResource . '(' . gettype($socketResource) . ') from registry.');
} else {
// Construct configuration entry for object factory and get it
$className = FrameworkConfiguration::getSelfInstance()->getConfigEntry($protocolName . '_connection_helper_class');
+ // Debug message
+ $factoryInstance->debugOutput('SOCKET-FACTORY: Going to use class ' . $className . ' for creating a socket resource ...');
+
// And call the static method
$socketResource = call_user_func($className . '::createConnectionFromPackageData', $packageData);
+ // Debug message
+ $factoryInstance->debugOutput('SOCKET-FACTORY: Created socket ' . $socketResource . '(' . gettype($socketResource) . ') from class ' . $className . '.');
+
// Construct container class, this won't be reached if an exception is thrown
$containerInstance = ObjectFactory::CreateObjectByConfiguredName('socket_container_class', array($socketResource, NULL, $packageData));
// Register it with the registry
Registry::getRegistry()->addInstance($registryKey, $containerInstance);
+
+ // Debug message
+ $factoryInstance->debugOutput('SOCKET-FACTORY: Socket is now registered in registry.');
}
// Return the resource
class BaseRawDataHandler extends BaseHandler {
// Error codes:
// - Socket raw data stream errors
- const SOCKET_ERROR_UNKNOWN = 'unknown_error'; // Unknown error (should not happen)
- const SOCKET_ERROR_TRANSPORT_ENDPOINT = 'transport_endpoint'; // Transport endpoint has closed
- const SOCKET_ERROR_EMPTY_DATA = 'empty_data'; // Other peer has sent nothing
- const SOCKET_ERROR_INVALID_BASE64_MODULO = 'base64_modulo'; // Length is not modulo 4
- const SOCKET_ERROR_INVALID_BASE64_MESSAGE = 'base64_message'; // Raw data is not Base64-encoded
- const SOCKET_ERROR_UNHANDLED = 'unhandled_package'; // Unhandled raw data (not bad)
- const SOCKET_ERROR_CONNECTION_REFUSED = 'connection_refused'; // The name says it: connection refused
- const SOCKET_ERROR_CONNECTION_TIMED_OUT = 'connection_timed_out'; // The name says it: connection attempt has timed-out
- const SOCKET_CONNECTED = 'connected'; // Nothing errorous happens, socket is connected
+ const SOCKET_ERROR_UNKNOWN = 'unknown_error'; // Unknown error (should not happen)
+ const SOCKET_ERROR_TRANSPORT_ENDPOINT = 'transport_endpoint'; // Transport endpoint has closed
+ const SOCKET_ERROR_EMPTY_DATA = 'empty_data'; // Other peer has sent nothing
+ const SOCKET_ERROR_INVALID_BASE64_MODULO = 'base64_modulo'; // Length is not modulo 4
+ const SOCKET_ERROR_INVALID_BASE64_MESSAGE = 'base64_message'; // Raw data is not Base64-encoded
+ const SOCKET_ERROR_UNHANDLED = 'unhandled_package'; // Unhandled raw data (not bad)
+ const SOCKET_ERROR_CONNECTION_REFUSED = 'connection_refused'; // The name says it: connection refused
+ const SOCKET_ERROR_CONNECTION_TIMED_OUT = 'connection_timed_out'; // The name says it: connection attempt has timed-out
+ const SOCKET_ERROR_OPERATION_IN_PROGRESS = 'operation_in_progress'; // 'Operation now in progress'
+ const SOCKET_ERROR_OPERATION_ALREADY_PROGRESS = 'operation_already_progress'; // 'Operation already in progress'
+ const SOCKET_ERROR_RESOURCE_UNAVAILABLE = 'resource_unavailable'; // 'Resource temporary unavailable'
+ const SOCKET_ERROR_NO_ROUTE_TO_HOST = 'no_route_to_host'; // The name says it: no route to host
+ const SOCKET_CONNECTED = 'connected'; // Nothing errorous happens, socket is connected
// - Package errors
const PACKAGE_ERROR_INVALID_DATA = 'invalid_data'; // Invalid data in package found
*/
private $diff = 0;
+ /**
+ * Whether this connection is initialized
+ */
+ private $isInitialized = false;
+
/**
* Wether this connection is shutted down
*/
return $class;
}
+ /**
+ * Getter for port number to satify ProtocolHandler
+ *
+ * @return $port The port number
+ */
+ public final function getPort () {
+ return $this->port;
+ }
+
+ /**
+ * Setter for port number to satify ProtocolHandler
+ *
+ * @param $port The port number
+ * @return void
+ */
+ protected final function setPort ($port) {
+ $this->port = $port;
+ }
+
+ /**
+ * Getter for protocol
+ *
+ * @return $protocol Used protocol
+ */
+ public final function getProtocol () {
+ return $this->protocol;
+ }
+
+ /**
+ * Setter for protocol
+ *
+ * @param $protocol Used protocol
+ * @return void
+ */
+ protected final function setProtocol ($protocol) {
+ $this->protocol = $protocol;
+ }
+
+ /**
+ * Getter for IP address
+ *
+ * @return $address The IP address
+ */
+ public final function getAddress () {
+ return $this->address;
+ }
+
+ /**
+ * Setter for IP address
+ *
+ * @param $address The IP address
+ * @return void
+ */
+ protected final function setAddress ($address) {
+ $this->address = $address;
+ }
+
+ /**
+ * Initializes the current connection
+ *
+ * @return void
+ * @throws SocketOptionException If setting any socket option fails
+ */
+ protected function initConnection () {
+ // Get socket resource
+ $socketResource = $this->getSocketResource();
+
+ // Set the option to reuse the port
+ if (!socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1)) {
+ // Handle this socket error with a faked recipientData array
+ $this->handleSocketError($socketResource, array('0.0.0.0', '0'));
+
+ // And throw again
+ // @TODO Move this to the socket error handler
+ throw new SocketOptionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ /*
+ * Set socket to non-blocking mode before trying to establish a link to
+ * it. This is now the default behaviour for all connection helpers who
+ * call initConnection(); .
+ */
+ if (!socket_set_nonblock($socketResource)) {
+ // Handle this socket error with a faked recipientData array
+ $helperInstance->handleSocketError($socketResource, array('0.0.0.0', '0'));
+
+ // And throw again
+ throw new SocketOptionException(array($helperInstance, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ // Last step: mark connection as initialized
+ $this->isInitialized = true;
+ }
+
+ /**
+ * Attempts to connect to a peer by given IP number and port from a valid
+ * recipientData array with currently configured timeout.
+ *
+ * @param $recipientData A valid recipient data array, 0=IP; 1=PORT
+ * @return $isConnected Wether the connection went fine
+ * @see Please see http://de.php.net/manual/en/function.socket-connect.php#84465 for original code
+ * @todo Rewrite the while() loop to a iterator to not let the software stay very long here
+ */
+ protected function connectToPeerByRecipientDataArray (array $recipientData) {
+ // Only call this if the connection is initialized by initConnection()
+ assert($this->isInitialized === true);
+
+ // Get current time
+ $time = time();
+
+ // "Cache" socket resource and timeout config
+ $socketResource = $this->getSocketResource();
+ $timeout = $this->getConfigInstance()->getConfigEntry('socket_timeout_seconds');
+
+ // Try to connect until it is connected
+ while ($isConnected = !@socket_connect($socketResource, $recipientData[0], $recipientData[1])) {
+ // Get last socket error
+ $socketError = socket_last_error($socketResource);
+
+ // Skip any errors which may happen on non-blocking connections
+ if (($socketError == SOCKET_EINPROGRESS) || ($socketError == SOCKET_EALREADY)) {
+ // Now, is that attempt within parameters?
+ if ((time() - $time) >= $timeout) {
+ // Didn't work within timeout
+ $isConnected = false;
+ break;
+ } // END - if
+
+ // Sleep about one second
+ $this->idle(1000);
+ } elseif ($socketError != 0) {
+ // Stop on everything else pronto
+ $isConnected = false;
+ break;
+ }
+ } // END - while
+
+ // Return status
+ return $isConnected;
+ }
+
/**
* Static "getter" for this connection class' name
*
}
}
- /**
- * Getter for port number to satify ProtocolHandler
- *
- * @return $port The port number
- */
- public final function getPort () {
- return $this->port;
- }
-
- /**
- * Setter for port number to satify ProtocolHandler
- *
- * @param $port The port number
- * @return void
- */
- protected final function setPort ($port) {
- $this->port = $port;
- }
-
- /**
- * Getter for protocol
- *
- * @return $protocol Used protocol
- */
- public final function getProtocol () {
- return $this->protocol;
- }
-
- /**
- * Setter for protocol
- *
- * @param $protocol Used protocol
- * @return void
- */
- protected final function setProtocol ($protocol) {
- $this->protocol = $protocol;
- }
-
- /**
- * Getter for IP address
- *
- * @return $address The IP address
- */
- public final function getAddress () {
- return $this->address;
- }
-
- /**
- * Setter for IP address
- *
- * @param $address The IP address
- * @return void
- */
- protected final function setAddress ($address) {
- $this->address = $address;
- }
-
/**
* "Accept" a visitor by simply calling it back
*
protected final function markConnectionShuttedDown () {
/* NOISY-DEBUG: */ $this->debugOutput('CONNECTION: ' . $this->__toString() . ' has been marked as shutted down');
$this->shuttedDown = true;
+
+ // And remove the (now invalid) socket
+ $this->setSocketResource(false);
}
/**
* later debugging purposes.
*
* @param $socketResource A valid socket resource
+ * @return void
* @throws SocketConnectionException The connection attempts fails with a time-out
*/
protected function socketErrorConnectionTimedOutHandler ($socketResource) {
// Throw it again
throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
}
+
+ /**
+ * Handles socket error 'resource temporary unavailable', but does not
+ * clear it for later debugging purposes.
+ *
+ * @param $socketResource A valid socket resource
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorResourceUnavailableHandler ($socketResource) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket error 'connection refused', but does not clear it for
+ * later debugging purposes.
+ *
+ * @param $socketResource A valid socket resource
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorConnectionRefusedHandler ($socketResource) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket error 'no route to host', but does not clear it for later
+ * debugging purposes.
+ *
+ * @param $socketResource A valid socket resource
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorNoRouteToHostHandler ($socketResource) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket error 'operation already in progress' which happens in
+ * method connectToPeerByRecipientDataArray() on timed out connection
+ * attempts.
+ *
+ * @param $socketResource A valid socket resource
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorOperationAlreadyProgressHandler ($socketResource) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Half-shutdown this socket (see there for difference to shutdownSocket())
+ $this->halfShutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket "error" 'operation now in progress' which can be safely
+ * passed on with non-blocking connections.
+ *
+ * @param $socketResource A valid socket resource
+ * @return void
+ */
+ protected function socketErrorOperationInProgressHandler ($socketResource) {
+ $this->debugOutput('CONNECTION: Operation is now in progress, this is usual for non-blocking connections and no bug.');
+ }
}
// [EOF]
throw new SocketCreationException(array($helperInstance, gettype($socketResource), $socketError, socket_strerror($socketError)), BaseListener::EXCEPTION_SOCKET_CREATION_FAILED);
} // END - if
- // Set the option to reuse the port
- if (!socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1)) {
- // Handle this socket error with a faked recipientData array
- $helperInstance->handleSocketError($socketResource, array('0.0.0.0', '0'));
-
- // And throw again
- throw new SocketOptionException(array($helperInstance, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- } // END - if
-
- // Set socket in non-blocking mode
- if (!socket_set_nonblock($socketResource)) {
- // Handle this socket error with a faked recipientData array
- $helperInstance->handleSocketError($socketResource, array('0.0.0.0', '0'));
-
- // And throw again
- throw new SocketOptionException(array($helperInstance, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- } // END - if
-
// Set the resource
$helperInstance->setSocketResource($socketResource);
+ // Init connection
+ $helperInstance->initConnection();
+
// @TODO The whole resolving part should be moved out and made more configurable
// Init recipient data
$recipientData = NULL;
$helperInstance->debugOutput('CONNECTION: Connecting to ' . $recipientData[0] . ':' . $recipientData[1]);
// Now connect to it
- if (!@socket_connect($socketResource, $recipientData[0], $recipientData[1])) {
+ if (!$helperInstance->connectToPeerByRecipientDataArray($recipientData)) {
// Handle socket error
- // @TODO Handle 115 error ("operation in progress")
$helperInstance->handleSocketError($socketResource, $recipientData);
- /*
- // Get socket error code for verification
- $socketError = socket_last_error($socketResource);
-
- // And throw again, but not for 'Operation now in progress'; the shutdownSocket() method should wait a little
- if ($socketError != 115) {
- // Get error message
- $errorMessage = socket_strerror($socketError);
-
- // Shutdown this socket
- $helperInstance->shutdownSocket($socketResource);
-
- // Throw it again
- throw new SocketConnectionException(array($helperInstance, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- } else {
- // Debug output
- $helperInstance->debugOutput('CONNECTION: Operation is in progress, this usual for non-blocking connections.');
- }
- */
} // END - if
// Connection is fully established here, so change the state
} // END - if
} // END - if
+ // Try to make blocking IO for socket_close()
+ socket_set_block($this->getSocketResource());
+
+ // Drop all data (don't sent any on socket closure)
+ socket_set_option($this->getSocketResource(), SOL_SOCKET, SO_LINGER, array('l_onoff' => 1, 'l_linger' => 0));
+
+ // Finally free some resources
+ socket_close($this->getSocketResource());
+
// Mark this connection as shutted down
$this->markConnectionShuttedDown();
}
*/
class BaseListener extends BaseHubSystem implements Visitable {
// Exception code constants
- const EXCEPTION_INVALID_SOCKET = 0xa00;
- const EXCEPTION_SOCKET_ALREADY_REGISTERED = 0xa01;
- const EXCEPTION_SOCKET_CREATION_FAILED = 0xa02;
- const EXCEPTION_NO_SOCKET_ERROR = 0xa03;
+ const EXCEPTION_INVALID_SOCKET = 0xa00;
+ const EXCEPTION_SOCKET_ALREADY_REGISTERED = 0xa01;
+ const EXCEPTION_SOCKET_CREATION_FAILED = 0xa02;
+ const EXCEPTION_NO_SOCKET_ERROR = 0xa03;
+ const EXCEPTION_CONNECTION_ALREADY_REGISTERED = 0xa04;
+ const EXCEPTION_UNEXPECTED_PACKAGE_STATUS = 0xa05;
/**
* Used protocol (Default: invalid, which is indeed invalid...)
// Return the prepared instance
return $listInstance;
}
+
+ /**
+ * "Getter" for an iterator instance of this list
+ *
+ * @return $iteratorInstance An instance of a Iterator class
+ * @todo 0% done
+ */
+ public function getListIterator () {
+ $this->partialStub('Please implement this method.');
+ }
+
+ /**
+ * Clears this list by cleaning up all groups together.
+ *
+ * @return void
+ * @todo 0% done
+ */
+ public function clearList () {
+ $this->partialStub('Please implement this method.');
+ }
}
// [EOF]
// Is there another list?
if (!is_null($list)) {
// Then get it as well
- $array = $this->listGroups[$list]->getArrayFromList(null);
+ $array = $this->listGroups[$list]->getArrayFromList(NULL);
} // END - if
// Walk through all entries
return $hash;
}
+ /**
+ * Clears an array of groups, all are being checked for existence
+ *
+ * @param $groupNames An array with existing list groups
+ * @return void
+ */
+ protected function clearGroups (array $groupNames) {
+ // Walk through all groups
+ foreach ($groupNames as $groupName) {
+ // Clear this group
+ $this->clearGroup($groupName);
+ } // END - foreach
+ }
+
+ /**
+ * Clears a single group by resetting it to its initial state (empty array)
+ *
+ * @param $groupName Name of an existing group to clear
+ * @return void
+ */
+ protected function clearGroup ($groupName) {
+ // Does this group exist?
+ if (!$this->isGroupSet($groupName)) {
+ // Throw the exception here
+ throw new NoListGroupException(array($this, $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
+ } // END - if
+
+ // Then clear this group list
+ $this->listGroups[$groupName]->clearList();
+
+ // Clear this list
+ $this->listIndex = array();
+ $this->listEntries = array();
+ }
+
/**
* Counts all entries in this list
*
public function getListIterator () {
$this->partialStub('Please implement this method.');
}
+
+ /**
+ * Clears this list by cleaning up all groups together.
+ *
+ * @return void
+ * @todo 0% done
+ */
+ public function clearList () {
+ $this->partialStub('Please implement this method.');
+ }
}
// [EOF]
* "Getter" for an iterator instance of this list
*
* @return $iteratorInstance An instance of a Iterator class
- * @todo0% done
+ * @todo 0% done
*/
public function getListIterator () {
$this->partialStub('Please implement this method.');
}
+
+ /**
+ * Clears this list by cleaning up all groups together.
+ *
+ * @return void
+ */
+ public function clearList () {
+ // Clear both groups together
+ $this->clearGroups(array('connected', 'disconnected'));
+ }
}
// [EOF]
// ... and return it
return $iteratorInstance;
}
+
+ /**
+ * Clears this list by cleaning up all groups together.
+ *
+ * @return void
+ */
+ public function clearList () {
+ // Clear the only one group
+ $this->clearGroup('pool');
+ }
}
// [EOF]
// ... and return it
return $iteratorInstance;
}
+
+ /**
+ * Clears this list by cleaning up all groups together.
+ *
+ * @return void
+ * @todo 0% done
+ */
+ public function clearList () {
+ $this->partialStub('Please implement this method.');
+ }
}
// [EOF]
* "Getter" for an iterator instance of this list
*
* @return $iteratorInstance An instance of a Iterator class
- * @todo0% done
+ * @todo 0% done
*/
public function getListIterator () {
$this->partialStub('Please implement this method.');
}
+
+ /**
+ * Clears this list by cleaning up all groups together.
+ *
+ * @return void
+ */
+ public function clearList () {
+ // Clear both groups
+ $this->clearGroups(array('ip_port', 'session_id'));
+ }
}
// [EOF]
* "Getter" for an iterator instance of this list
*
* @return $iteratorInstance An instance of a Iterator class
- * @todo0% done
+ * @todo 0% done
*/
public function getListIterator () {
$this->partialStub('Please implement this method.');
}
+
+ /**
+ * Clears this list by cleaning up all groups together.
+ *
+ * @return void
+ */
+ public function clearList () {
+ // Clear the only one group
+ $this->clearGroup('tasks');
+ }
}
// [EOF]
const INDEX_PACKAGE_SENDER = 0;
const INDEX_PACKAGE_RECIPIENT = 1;
const INDEX_PACKAGE_CONTENT = 2;
+ const INDEX_PACKAGE_STATUS = 3;
/**
* Named array elements for package data
const PACKAGE_DATA_SENDER = 'sender';
const PACKAGE_DATA_RECIPIENT = 'recipient';
const PACKAGE_DATA_CONTENT = 'content';
+ const PACKAGE_DATA_STATUS = 'status';
+
+ /**
+ * All package status
+ */
+ const PACKAGE_STATUS_NEW = 'new';
+ const PACKAGE_STATUS_FAILED = 'failed';
/**
* Tags seperator
*/
private function getHashFromContent ($content, HelpableHub $helperInstance, NodeHelper $nodeInstance) {
// Create the hash
- // @TODO crc32() is not very strong, but it needs to be fast
+ // @TODO crc32() is very weak, but it needs to be fast
$hash = crc32(
$content .
self::PACKAGE_CHECKSUM_SEPERATOR .
return $hash;
}
+ /**
+ * Change the package with given status in given stack
+ *
+ * @param $packageData Raw package data in an array
+ * @param $stackerName Name of the stacker
+ * @param $newStatus New status to set
+ * @return void
+ */
+ private function changePackageStatus (array $packageData, $stackerName, $newStatus) {
+ // Skip this for empty stacks
+ if ($this->getStackerInstance()->isStackEmpty($stackerName)) {
+ // This avoids an exception after all packages has failed
+ return;
+ } // END - if
+
+ // Pop the entry (it should be it)
+ $this->getStackerInstance()->popNamed($stackerName);
+
+ // Temporary set the new status
+ $packageData[self::PACKAGE_DATA_STATUS] = $newStatus;
+
+ // And push it again
+ $this->getStackerInstance()->pushNamed($stackerName, $packageData);
+ }
+
///////////////////////////////////////////////////////////////////////////
// Delivering packages / raw data
///////////////////////////////////////////////////////////////////////////
// Set the recipient
$packageData[self::PACKAGE_DATA_RECIPIENT] = $currentRecipient;
+ var_dump($packageData);
// And enqueue it to the writer class
$this->getStackerInstance()->pushNamed(self::STACKER_NAME_DECLARED, $packageData);
// Debug message
//* NOISY-DEBUG: */ $this->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after validatePeerStateConnected() has been called.');
- // We enqueue it again, but now in the out-going queue
+ // Enqueue it again on the out-going queue, the connection is up and working at this point
$this->getStackerInstance()->pushNamed(self::STACKER_NAME_OUTGOING, $packageData);
}
self::PACKAGE_DATA_SENDER => $nodeInstance->getSessionId(),
self::PACKAGE_DATA_RECIPIENT => $helperInstance->getRecipientType(),
self::PACKAGE_DATA_CONTENT => $content,
+ self::PACKAGE_DATA_STATUS => self::PACKAGE_STATUS_NEW
));
}
return;
} // END - if
- // Get the package again
+ // Get the package
$packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_DECLARED);
try {
} catch (InvalidStateException $e) {
// The state is not excepected (shall be 'connected')
$this->debugOutput('PACKAGE: Caught exception ' . $e->__toString() . ' with message=' . $e->getMessage());
+
+ // Mark the package with status failed
+ $this->changePackageStatus($packageData, self::STACKER_NAME_DECLARED, self::PACKAGE_STATUS_FAILED);
}
}
return;
} // END - if
- // Get the package again
+ // Get the package
$packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_OUTGOING);
try {
} catch (InvalidSocketException $e) {
// Output exception message
$this->debugOutput('PACKAGE: Package was not delivered: ' . $e->getMessage());
+
+ // Mark package as failed
+ $this->changePackageStatus($packageData, self::STACKER_NAME_OUTGOING, self::PACKAGE_STATUS_FAILED);
}
}
// Debug message
/* DEBUG: */ $this->debugOutput('PACKAGE: All stacker have been re-initialized.');
}
+
+ /**
+ * Removes the first failed outoging package from the stack to continue
+ * with next one (it will never work until the issue is fixed by you).
+ *
+ * @return void
+ * @throws UnexpectedPackageStatusException If the package status is not 'failed'
+ * @todo This may be enchanced for outgoing packages?
+ */
+ public function removeFirstFailedPackage () {
+ // Get the package again
+ $packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_DECLARED);
+
+ // Is the package status 'failed'?
+ if ($packageData[self::PACKAGE_DATA_STATUS] != self::PACKAGE_STATUS_FAILED) {
+ // Not failed!
+ throw new UnexpectedPackageStatusException(array($this, $packageData, self::PACKAGE_STATUS_FAILED), BaseListener::EXCEPTION_UNEXPECTED_PACKAGE_STATUS);
+ } // END - if
+
+ // Remove this entry
+ $this->getStackerInstance()->popNamed(self::STACKER_NAME_DECLARED);
+ }
}
// [EOF]
// Default is no socket
$socketResource = false;
+ // Debug message
+ /* DEBUG: */ $this->debugOutput('POOL: Checking ' . count($this->getAllSockets()) . ' socket(s) ...');
+
// Get all sockets and check them, skip the server socket
foreach ($this->getAllSockets() as $socket) {
// Is this a server socket?
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A Connection registry
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class ConnectionRegistry extends BaseRegistry implements Register, RegisterableConnection {
+ // Exception constants
+ const CONNECTION_NOT_REGISTERED = 0xd100;
+
+ /**
+ * Instance of this class
+ */
+ private static $registryInstance = NULL;
+
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Creates a singleton instance of this registry class
+ *
+ * @return $registryInstance An instance of this class
+ */
+ public static final function createConnectionRegistry () {
+ // Is an instance there?
+ if (is_null(self::$registryInstance)) {
+ // Not yet, so create one
+ self::$registryInstance = new ConnectionRegistry();
+ } // END - if
+
+ // Return the instance
+ return self::$registryInstance;
+ }
+
+ /**
+ * "Getter" to get a string respresentation for a key for the sub-registry
+ * in this format: class:protocol:port
+ *
+ * @param $connectionInstance An instance of a ConnectionHelper class
+ * @return $key A string representation of the socket for the registry
+ */
+ private function getSubRegistryKey (ConnectionHelper $connectionInstance) {
+ // Get protocol and port number and add both together
+ $key = sprintf("%s:%s:%s",
+ $connectionInstance->__toString(),
+ $connectionInstance->getProtocol(),
+ $connectionInstance->getPort()
+ );
+
+ // Return resulting key
+ return $key;
+ }
+
+ /**
+ * "Getter" to get a string respresentation of the protocol
+ *
+ * @param $connectionInstance An instance of a ConnectionHelper class
+ * @return $key A string representation of the protocol for the registry
+ */
+ private function getRegistryKeyFromProtocol (ConnectionHelper $connectionInstance) {
+ // Get the key
+ $key = $connectionInstance->getProtocol();
+
+ // Return resulting key
+ return $key;
+ }
+
+ /**
+ * Checks wether the given protocol is registered
+ *
+ * @param $connectionInstance An instance of a ConnectionHelper class
+ * @return $isRegistered Wether the protocol is registered
+ */
+ private function isProtocolRegistered (ConnectionHelper $connectionInstance) {
+ // Get the key
+ $key = $this->getRegistryKeyFromProtocol($connectionInstance);
+
+ // Determine it
+ $isRegistered = $this->instanceExists($key);
+
+ // Return result
+ return $isRegistered;
+ }
+
+ /**
+ * Checks wether given socket resource is registered. If $socketResource is
+ * false only the instance will be checked.
+ *
+ * @param $connectionInstance An instance of a ConnectionHelper class
+ * @param $socketResource A valid socket resource
+ * @return $isRegistered Wether the given socket resource is registered
+ */
+ public function isConnectionRegistered (ConnectionHelper $connectionInstance, $socketResource) {
+ // Default is not registered
+ $isRegistered = false;
+
+ // First, check for the instance, there can be only once
+ if ($this->isProtocolRegistered($connectionInstance)) {
+ // That one is found so "get" a registry key from it
+ $key = $this->getRegistryKeyFromProtocol($connectionInstance);
+
+ // Get the registry
+ $registryInstance = $this->getInstance($key);
+
+ // "Get" a key for the socket
+ $socketKey = $this->getSubRegistryKey($connectionInstance);
+
+ // And simply ask it
+ $isRegistered = $registryInstance->instanceExists($socketKey);
+ } // END - if
+
+ // Return the result
+ return $isRegistered;
+ }
+
+ /**
+ * Registeres given socket for listener or throws an exception if it is already registered
+ *
+ * @param $connectionInstance An instance of a ConnectionHelper class
+ * @param $socketResource A valid socket resource
+ * @param $packageData Optional raw package data
+ * @throws ConnectionAlreadyRegisteredException If the given socket is already registered
+ * @return void
+ */
+ public function registerConnection (ConnectionHelper $connectionInstance, $socketResource, array $packageData = array()) {
+ // Is the socket already registered?
+ if ($this->isConnectionRegistered($connectionInstance, $socketResource)) {
+ // Throw the exception
+ throw new ConnectionAlreadyRegisteredException(array($connectionInstance, $socketResource), BaseListener::EXCEPTION_CONNECTION_ALREADY_REGISTERED);
+ } // END - if
+
+ // Does the instance exist?
+ if (!$this->isProtocolRegistered($connectionInstance)) {
+ // No, not found so we create a sub registry (not needed to configure!)
+ $registryInstance = SubRegistry::createSubRegistry();
+
+ // Now we can create the sub-registry for this protocol
+ $this->addInstance($this->getRegistryKeyFromProtocol($connectionInstance), $registryInstance);
+ } else {
+ // Get the sub-registry back
+ $registryInstance = $this->getInstance($this->getRegistryKeyFromProtocol($connectionInstance));
+ }
+
+ // Get a key for sub-registries
+ $socketKey = $this->getSubRegistryKey($connectionInstance);
+
+ // Get a socket container
+ $socketInstance = ObjectFactory::CreateObjectByConfiguredName('socket_container_class', array($socketResource, $connectionInstance, $packageData));
+
+ // We have a sub-registry, the socket key and the socket, now we need to put all together
+ /* DEBUG: */ $this->debugOutput('CONNECTION-REGISTRY: socketKey=' . $socketKey . ',socketResource=' . $socketResource . ' - adding socket container instance ...');
+ $registryInstance->addInstance($socketKey, $socketInstance);
+ }
+
+ /**
+ * Getter for given listener's socket resource
+ *
+ * @param $connectionInstance An instance of a ConnectionHelper class
+ * @return $socketResource A valid socket resource
+ * @throws NoConnectionRegisteredException If the requested socket is not registered
+ */
+ public function getRegisteredConnectionResource (ConnectionHelper $connectionInstance) {
+ // The socket must be registered before we can return it
+ if (!$this->isConnectionRegistered($connectionInstance, false)) {
+ // Throw the exception
+ throw new NoConnectionRegisteredException ($connectionInstance, self::CONNECTION_NOT_REGISTERED);
+ } // END - if
+
+ // Now get the key from the protocol
+ $key = $this->getRegistryKeyFromProtocol($connectionInstance);
+
+ // And get the registry
+ $registryInstance = $this->getInstance($key);
+
+ // Get a socket key
+ $socketKey = $this->getSubRegistryKey($connectionInstance);
+
+ // And the final socket resource
+ $socketResource = $registryInstance->getInstance($socketKey)->getConnectionResource();
+
+ // Return the resource
+ return $socketResource;
+ }
+
+ /**
+ * "Getter" for protocol/connection instance from given package data
+ *
+ * @param $packageData Raw package data
+ * @return $connectionInstance An instance of a ConnectionHelper class
+ */
+ public function getHandlerInstanceFromPackageData (array $packageData) {
+ // Init protocol instance
+ $connectionInstance = NULL;
+
+ // Get all keys and check them
+ foreach ($this->getInstanceRegistry() as $key=>$registryInstance) {
+ // This is always a SubRegistry instance
+ foreach ($registryInstance->getInstanceRegistry() as $subKey=>$containerInstance) {
+ // This is a ConnectionContainer instance, so does the recipient match?
+ if ($containerInstance->ifAddressMatches($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])) {
+ // Found one, so get the protocol instance and abort any further search
+ $connectionInstance = $containerInstance->getProtocolInstance();
+ break;
+ } // END - if
+ } // END - foreach
+ } // END - foreach
+
+ // Return the protocol instance
+ return $connectionInstance;
+ }
+}
+
+// [EOF]
+?>
// Is the socket already registered?
if ($this->isSocketRegistered($protocolInstance, $socketResource)) {
// Throw the exception
- throw new SocketAlreadyRegisteredException($protocolInstance, BaseListener::EXCEPTION_SOCKET_ALREADY_REGISTERED);
+ throw new SocketAlreadyRegisteredException(array($protocolInstance, $socketResource), BaseListener::EXCEPTION_SOCKET_ALREADY_REGISTERED);
} // END - if
// Does the instance exist?
$socketInstance = ObjectFactory::CreateObjectByConfiguredName('socket_container_class', array($socketResource, $protocolInstance, $packageData));
// We have a sub-registry, the socket key and the socket, now we need to put all together
- /* DEBUG: */ $this->debugOutput('SOCKET-REGISTRY: socketKey=' . $socketKey . ',socketResource=' . $socketResource);
+ /* DEBUG: */ $this->debugOutput('SOCKET-REGISTRY: socketKey=' . $socketKey . ',socketResource=' . $socketResource . ' - adding socket container instance ...');
$registryInstance->addInstance($socketKey, $socketInstance);
}
* @param $packageData Raw package data
* @param $socketResource A valid socket resource
* @return $stateInstance An instance of the resolved state
+ * @throws InvalidSocketException If socketResource, even from getSocketResource() is no valid resource
* @todo ~30% done
*/
public static function resolveStateByPackage (ConnectionHelper $helperInstance, array $packageData, $socketResource) {
if (!is_resource($socketResource)) {
// No, so get socket resource from helper
$socketResource = $helperInstance->getSocketResource();
+
+ // Still no socket resource?
+ if (!is_resource($socketResource)) {
+ // Then abort here with an exception (may happen after socket_shutdown())
+ throw new InvalidSocketException(array($helperInstance, $socketResource, 'unknown', 'unknown'), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
} // END - if
// Get error code from it
parent::__construct(__CLASS__);
// Set state name
- $this->setStateName('!!!');
+ $this->setStateName(BaseRawDataHandler::SOCKET_ERROR_!!!);
}
/**
parent::__construct(__CLASS__);
// Set state name
- $this->setStateName('connected');
+ $this->setStateName(BaseRawDataHandler::SOCKET_CONNECTED);
}
/**
parent::__construct(__CLASS__);
// Set state name
- $this->setStateName('connection_refused');
+ $this->setStateName(BaseRawDataHandler::SOCKET_ERROR_CONNECTION_REFUSED);
}
/**
parent::__construct(__CLASS__);
// Set state name
- $this->setStateName('connection_timed_out');
+ $this->setStateName(BaseRawDataHandler::SOCKET_ERROR_CONNECTION_TIMED_OUT);
}
/**
--- /dev/null
+<?php
+/**
+ * A NoRouteToHost peer state class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class NoRouteToHostPeerState extends BasePeerState implements PeerStateable {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set state name
+ $this->setStateName(BaseRawDataHandler::SOCKET_ERROR_NO_ROUTE_TO_HOST);
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @return $stateInstance An instance of a PeerStateable class
+ */
+ public final static function createNoRouteToHostPeerState () {
+ // Get new instance
+ $stateInstance = new NoRouteToHostPeerState();
+
+ // Return the prepared instance
+ return $stateInstance;
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+<?php
+/**
+ * A OperationAlreadyProgress peer state class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class OperationAlreadyProgressPeerState extends BasePeerState implements PeerStateable {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set state name
+ $this->setStateName(BaseRawDataHandler::SOCKET_ERROR_OPERATION_ALREADY_PROGRESS);
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @return $stateInstance An instance of a PeerStateable class
+ */
+ public final static function createOperationAlreadyProgressPeerState () {
+ // Get new instance
+ $stateInstance = new OperationAlreadyProgressPeerState();
+
+ // Return the prepared instance
+ return $stateInstance;
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+<?php
+/**
+ * A TransportEndpointGone peer state class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class TransportEndpointGonePeerState extends BasePeerState implements PeerStateable {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set state name
+ $this->setStateName(BaseRawDataHandler::SOCKET_ERROR_TRANSPORT_ENDPOINT);
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @return $stateInstance An instance of a PeerStateable class
+ */
+ public final static function createTransportEndpointGonePeerState () {
+ // Get new instance
+ $stateInstance = new TransportEndpointGonePeerState();
+
+ // Return the prepared instance
+ return $stateInstance;
+ }
+}
+
+// [EOF]
+?>
<?php
-/**
- * A TransportEndpointGone peer state class
- *
- * @author Roland Haeder <webmaster@ship-simu.org>
- * @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
- * @license GNU GPL 3.0 or any newer version
- * @link http://www.ship-simu.org
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-class TransportEndpointGonePeerState extends BasePeerState implements PeerStateable {
- /**
- * Protected constructor
- *
- * @return void
- */
- protected function __construct () {
- // Call parent constructor
- parent::__construct(__CLASS__);
-
- // Set state name
- $this->setStateName('transport_endpoint');
- }
-
- /**
- * Creates an instance of this class
- *
- * @return $stateInstance An instance of a PeerStateable class
- */
- public final static function createTransportEndpointGonePeerState () {
- // Get new instance
- $stateInstance = new TransportEndpointGonePeerState();
-
- // Return the prepared instance
- return $stateInstance;
- }
-}
-
-// [EOF]
+// @DEPRECATED
?>
* @return $isExhausted Wether the retry count has been reached
*/
public static function isConnectRetryExhausted (ConnectionHelper $helperInstance) {
- //* DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ' - ENTERED!');
+ //* NOISY-DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ' - ENTERED!');
// Construct config entry
$configEntry = $helperInstance->getProtocol() . '_connect_retry_max';
);
// Return it
- //* DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ',isExhausted=' . intval($isExhausted) . ' - EXIT!');
+ //* NOISY-DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ',isExhausted=' . intval($isExhausted) . ' - EXIT!');
return $isExhausted;
}
* @return void
*/
public static function increaseConnectRetry (ConnectionHelper $helperInstance) {
- //* DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ' - ENTERED!');
+ //* NOISY-DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ' - ENTERED!');
// Is the counter there
if (!isset(self::$connectionStatistics[$helperInstance->getProtocol()][$helperInstance->__toString()]['retry_count'])) {
// First attempt
- //* DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ' - FIRST!');
+ //* NOISY-DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ' - FIRST!');
self::$connectionStatistics[$helperInstance->getProtocol()][$helperInstance->__toString()]['retry_count'] = 1;
} else {
// Next attempt
- //* DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ' - INCREMENT!');
+ //* NOISY-DEBUG: */ $helperInstance->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: helperInstance=' . $helperInstance->__toString() . ' - INCREMENT!');
self::$connectionStatistics[$helperInstance->getProtocol()][$helperInstance->__toString()]['retry_count']++;
}
--- /dev/null
+<?php
+/**
+ * A HalfShutdownSocket visitor
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class HalfShutdownSocketVisitor extends BaseVisitor implements Visitor {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set visitor mode
+ $this->setVisitorMode('socket');
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @return $visitorInstance An instance a Visitorable class
+ */
+ public static final function createHalfShutdownSocketVisitor () {
+ // Get new instance
+ $visitorInstance = new HalfShutdownSocketVisitor();
+
+ // Return the prepared instance
+ return $visitorInstance;
+ }
+
+ /**
+ * "Visit" method to do the actual request. Here we want to shutdown the
+ * attached socket.
+ *
+ * @param $helperInstance An instance of a ConnectionHelper class
+ * @return void
+ */
+ public function visitConnectionHelper (ConnectionHelper $helperInstance) {
+ // Do we have reached the retry count?
+ if (ConnectionStatisticsHelper::isConnectRetryExhausted($helperInstance)) {
+ // Also visit the network package to clear any out-going packages
+ NetworkPackageFactory::createNetworkPackageInstance()->accept($this);
+
+ // Still shutdown the visitor (look in visitNetworkPackage() for details)
+ $helperInstance->doShutdown();
+ } else {
+ // We can still move on and retry the connection attempt
+ ConnectionStatisticsHelper::increaseConnectRetry($helperInstance);
+ }
+ }
+
+ /**
+ * "Visit" method to do the actual request. This method does remove the last
+ * failed package from the stack because all retries are fully exhausted
+ * (see visitConnectionHelper() for the logic).
+ *
+ * @param $packageInstance An instance of a Deliverable class
+ * @return void
+ */
+ public function visitNetworkPackage (Deliverable $packageInstance) {
+ // Just call it back
+ $packageInstance->removeFirstFailedPackage();
+ }
+}
+
+// [EOF]
+?>
./application/hub/interfaces/helper/connections/class_ConnectionHelper.php:38: * @todo We may want to implement a filter for ease notification of other objects like our pool
./application/hub/interfaces/helper/messages/class_MessageHelper.php:10: * @todo Please find another name for this interface
./application/hub/interfaces/nodes/class_NodeHelper.php:10: * @todo We need to find a better name for this interface
+./application/hub/main/class_BaseHubSystem.php:300: // @TODO On some systems it is 134, on some 107?
./application/hub/main/commands/console/class_HubConsoleChatCommand.php:107: * @todo Should we add some more filters?
./application/hub/main/commands/console/class_HubConsoleChatCommand.php:58: * @todo Try to create a ChatActivationTask or so
./application/hub/main/commands/console/class_HubConsoleCruncherCommand.php:107: * @todo Should we add some more filters?
./application/hub/main/cruncher/mcrypt/class_HubMcryptCruncher.php:108: * @todo Implement this method
./application/hub/main/cruncher/mcrypt/class_HubMcryptCruncher.php:138: * @todo 0% done
./application/hub/main/cruncher/mcrypt/class_HubMcryptCruncher.php:98: // @TODO Implement this method
-./application/hub/main/database/wrapper/states/class_PeerStateLookupDatabaseWrapper.php:170: * @todo Unfinished area
-./application/hub/main/database/wrapper/states/class_PeerStateLookupDatabaseWrapper.php:212: * @todo Unfinished area
+./application/hub/main/database/wrapper/states/class_PeerStateLookupDatabaseWrapper.php:177: * @todo Unfinished area
+./application/hub/main/database/wrapper/states/class_PeerStateLookupDatabaseWrapper.php:219: * @todo Unfinished area
./application/hub/main/discovery/socket/class_PackageSocketDiscovery.php:102: // @TODO We may need some logging here
./application/hub/main/factories/socket/class_SocketFactory.php:10: * @todo Find an interface for hub helper
./application/hub/main/filter/bootstrap/chat/class_ChatBootstrapGenericActivationFilter.php:54: * @todo Maybe we want to do somthing more here?
./application/hub/main/filter/task/chat/class_ChatTaskHandlerInitializerFilter.php:55: * @todo 5% done
./application/hub/main/filter/task/cruncher/class_CruncherTaskHandlerInitializerFilter.php:55: * @todo 5% done
./application/hub/main/filter/task/node/class_NodeTaskHandlerInitializerFilter.php:55: * @todo Maybe some more tasks needs to be added?
-./application/hub/main/handler/network/class_BaseRawDataHandler.php:144: * @todo This method will be moved to a better place
-./application/hub/main/handler/network/class_BaseRawDataHandler.php:151: // @TODO Numeric or alpha-numeric index?
+./application/hub/main/handler/network/class_BaseRawDataHandler.php:149: * @todo This method will be moved to a better place
+./application/hub/main/handler/network/class_BaseRawDataHandler.php:156: // @TODO Numeric or alpha-numeric index?
./application/hub/main/handler/network/udp/class_UdpRawDataHandler.php:58: * @todo 0%
./application/hub/main/handler/tasks/class_TaskHandler.php:140: // @TODO Messurement can be added around this call
+./application/hub/main/helper/connection/class_BaseConnectionHelper.php:182: // @TODO Move this to the socket error handler
+./application/hub/main/helper/connection/class_BaseConnectionHelper.php:210: * @todo Rewrite the while() loop to a iterator to not let the software stay very long here
./application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php:10: * @todo Find an interface for hub helper
-./application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php:149: * @todo We may want to implement a filter for ease notification of other objects like our pool
+./application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php:143: * @todo We may want to implement a filter for ease notification of other objects like our pool
+./application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php:47: * @todo $errorCode/-Message are now in handleSocketError()'s call-back methods
+./application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php:84: // @TODO The whole resolving part should be moved out and made more configurable
./application/hub/main/helper/connection/udp/class_UdpConnectionHelper.php:10: * @todo Find an interface for hub helper
-./application/hub/main/helper/connection/udp/class_UdpConnectionHelper.php:54: * @todo We may want to implement a filter for ease notification of other objects like our pool
+./application/hub/main/helper/connection/udp/class_UdpConnectionHelper.php:54: * @todo Implement a filter for ease notification of other objects like the pool
./application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php:10: * @todo Find an interface for hub helper
./application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php:61: * @todo Rewrite the ->renderXmlContent() call to no arguments
./application/hub/main/helper/hub/connection/class_HubSelfConnectHelper.php:10: * @todo Find an interface for hub helper
./application/hub/main/iterator/pool/monitor/class_MonitorPoolIterator.php:11: * @todo latency-based iteration or similar approaches
./application/hub/main/iterator/pool/tasks/class_TaskPoolIterator.php:10: * @todo This current implementation is not recommended, use a
./application/hub/main/iterator/pool/tasks/class_TaskPoolIterator.php:11: * @todo latency-based iteration or similar approaches
-./application/hub/main/listener/udp/class_UdpListener.php:139: * @todo ~50% done
+./application/hub/main/listener/udp/class_UdpListener.php:151: * @todo ~50% done
./application/hub/main/lists/class_BaseList.php:264: // @TODO Extend this somehow?
./application/hub/main/lists/groups/class_ListGroupList.php:52: * @todo 0% done
-./application/hub/main/lists/hub/class_HubList.php:56: * @todo0% done
-./application/hub/main/lists/recipient/class_RecipientList.php:59: * @todo0% done
-./application/hub/main/lists/tasks/class_TaskList.php:55: * @todo0% done
+./application/hub/main/lists/groups/class_ListGroupList.php:62: * @todo 0% done
+./application/hub/main/lists/hub/class_HubList.php:56: * @todo 0% done
+./application/hub/main/lists/query/local/class_LocalQueryList.php:68: * @todo 0% done
+./application/hub/main/lists/recipient/class_RecipientList.php:59: * @todo 0% done
+./application/hub/main/lists/tasks/class_TaskList.php:55: * @todo 0% done
./application/hub/main/nodes/boot/class_HubBootNode.php:119: // @TODO Add some filters here
./application/hub/main/nodes/boot/class_HubBootNode.php:58: * @todo add some more special bootstrap things for this boot node
./application/hub/main/nodes/boot/class_HubBootNode.php:99: * @todo Unfinished method
./application/hub/main/nodes/regular/class_HubRegularNode.php:58: * @todo Implement this method
./application/hub/main/nodes/regular/class_HubRegularNode.php:68: * @todo Unfinished method
./application/hub/main/nodes/regular/class_HubRegularNode.php:91: // @TODO Add some filters here
-./application/hub/main/package/class_NetworkPackage.php:210: * @todo $helperInstance is unused
-./application/hub/main/package/class_NetworkPackage.php:214: // @TODO crc32() is not very strong, but it needs to be fast
+./application/hub/main/package/class_NetworkPackage.php:218: * @todo $helperInstance is unused
+./application/hub/main/package/class_NetworkPackage.php:222: // @TODO crc32() is very weak, but it needs to be fast
./application/hub/main/package/class_NetworkPackage.php:23: * @todo Needs to add functionality for handling the object's type
-./application/hub/main/package/class_NetworkPackage.php:336: // @TODO We may want to do somthing more here?
-./application/hub/main/package/class_NetworkPackage.php:435: // @TODO Add some logging here
-./application/hub/main/package/class_NetworkPackage.php:461: // @TODO Add some logging here
-./application/hub/main/package/class_NetworkPackage.php:559: // @TODO Add some logging here
-./application/hub/main/package/class_NetworkPackage.php:637: // @TODO Add some content here
-./application/hub/main/package/fragmenter/class_PackageFragmenter.php:426: * @todo $helperInstance is unused
-./application/hub/main/pools/peer/class_DefaultPeerPool.php:149: // @TODO Check for IP
+./application/hub/main/package/class_NetworkPackage.php:386: // @TODO We may want to do somthing more here?
+./application/hub/main/package/class_NetworkPackage.php:486: // @TODO Add some logging here
+./application/hub/main/package/class_NetworkPackage.php:512: // @TODO Add some logging here
+./application/hub/main/package/class_NetworkPackage.php:616: // @TODO Add some logging here
+./application/hub/main/package/class_NetworkPackage.php:695: // @TODO Add some content here
+./application/hub/main/package/class_NetworkPackage.php:745: * @todo This may be enchanced for outgoing packages?
+./application/hub/main/package/fragmenter/class_PackageFragmenter.php:427: * @todo $helperInstance is unused
+./application/hub/main/pools/peer/class_DefaultPeerPool.php:160: // @TODO Check for IP
./application/hub/main/producer/cruncher/keys/class_CruncherKeyProducer.php:106: // @TODO Do something with it
./application/hub/main/producer/cruncher/keys/class_CruncherKeyProducer.php:62: * @todo Find something for init phase of this key producer
./application/hub/main/producer/cruncher/keys/class_CruncherKeyProducer.php:72: * @todo ~30% done
./application/hub/main/producer/cruncher/work_units/class_CruncherTestUnitProducer.php:79: * @todo ~60% done
./application/hub/main/producer/cruncher/work_units/class_CruncherTestUnitProducer.php:99: // @TODO Unfinished work here
-./application/hub/main/resolver/state/peer/class_PeerStateResolver.php:58: * @todo ~30% done
-./application/hub/main/resolver/state/peer/class_PeerStateResolver.php:79: // @TODO On some systems it is 134, on some 107?
+./application/hub/main/resolver/state/peer/class_PeerStateResolver.php:59: * @todo ~30% done
./application/hub/main/states/node/init/class_NodeInitState.php:60: * @todo We might want to move some calls to this method to fill it with life
./application/hub/main/statistics/connection/class_ConnectionStatisticsHelper.php:11: * @todo Find an interface for hub helper
./application/hub/main/streams/raw_data/input/class_RawDataInputStream.php:57: * @todo Do we need to do something more here?
./application/hub/main/streams/raw_data/output/class_RawDataOutputStream.php:53: * @todo Do we need to do something more here?
+./application/hub/main/tasks/chat/class_ChatTelnetListenerTask.php:53: * @todo Maybe visit some sub-objects
+./application/hub/main/tasks/chat/class_ChatTelnetListenerTask.php:64: * @todo 0%
./application/hub/main/tasks/cruncher/class_CruncherKeyProducerTask.php:53: * @todo Maybe visit some sub-objects
./application/hub/main/tasks/cruncher/class_CruncherTestUnitProducerTask.php:53: * @todo Maybe visit some sub-objects
./application/hub/main/tasks/cruncher/class_CruncherWorkUnitFetcherTask.php:54: * @todo Maybe visit some sub-objects
./application/hub/main/tasks/hub/announcement/class_HubSelfAnnouncementTask.php:53: * @todo 0%
./application/hub/main/tasks/hub/class_HubSelfConnectTask.php:53: * @todo 0%
-./application/hub/main/tasks/hub/class_HubSocketListenerTask.php:62: // @TODO Do we need to visit this task? $visitorInstance->visitTask($this);
-./application/hub/main/tasks/hub/class_HubSocketListenerTask.php:69: * @todo 0% done
+./application/hub/main/tasks/hub/class_HubSocketListenerTask.php:63: // @TODO Do we need to visit this task? $visitorInstance->visitTask($this);
+./application/hub/main/tasks/hub/class_HubSocketListenerTask.php:70: * @todo 0% done
./application/hub/main/tasks/hub/ping/class_HubPingTask.php:73: * @todo 0% done
./application/hub/main/tasks/hub/update/class_HubUpdateCheckTask.php:53: * @todo 0%
./application/hub/main/template/announcement/class_XmlAnnouncementTemplateEngine.php:10: * @todo This template engine does not make use of setTemplateType()
./inc/classes/exceptions/main/class_MissingMethodException.php:13: * @todo Try to rewrite user/guest login classes and mark this exception as deprecated
./inc/classes/exceptions/main/class_NoConfigEntryException.php:10: * @todo Rename this class to NoFoundEntryException
./inc/classes/interfaces/class_FrameworkInterface.php:11: * @todo Find a better name for this interface
-./inc/classes/main/class_BaseFrameworkSystem.php:1263: * @todo Write a logging mechanism for productive mode
-./inc/classes/main/class_BaseFrameworkSystem.php:1277: // @TODO Finish this part!
+./inc/classes/main/class_BaseFrameworkSystem.php:1294: * @todo Write a logging mechanism for productive mode
+./inc/classes/main/class_BaseFrameworkSystem.php:1308: // @TODO Finish this part!
./inc/classes/main/class_BaseFrameworkSystem.php:195: // @todo Try to clean these constants up
-./inc/classes/main/class_BaseFrameworkSystem.php:434: * @todo SearchableResult and UpdateableResult shall have a super interface to use here
+./inc/classes/main/class_BaseFrameworkSystem.php:458: * @todo SearchableResult and UpdateableResult shall have a super interface to use here
./inc/classes/main/commands/web/class_WebLoginAreaCommand.php:64: * @todo Add some stuff here: Some personal data, app/game related data
./inc/classes/main/commands/web/class_WebProblemCommand.php:58: * @todo 0% done
./inc/classes/main/commands/web/class_WebStatusCommand.php:58: * @todo 0% done
./inc/classes/main/user/member/class_Member.php:84: * @todo Add more ways over creating user classes
./inc/classes/middleware/debug/class_DebugMiddleware.php:112: // @TODO Initialization phase
./inc/classes.php:10: * @todo We should minimize these includes
-./inc/config/class_FrameworkConfiguration.php:172: * @todo We have to add some more entries from $_SERVER here
+./inc/config/class_FrameworkConfiguration.php:175: * @todo We have to add some more entries from $_SERVER here
./inc/database.php:11: * @todo We should minimize these includes
./inc/database.php:51:// @TODO Rewrite this
./inc/hooks.php:11: * @todo We should minimize these includes
./inc/hooks.php:28:// @TODO This makes the core depending on the SPL. But it should be installed anyway.
./inc/includes.php:11: * @todo We should minimize these includes
./inc/includes.php:38:// @TODO Find a nicer OOP-ed way for this
-./inc/loader/class_ClassLoader.php:264: /* @todo: Do not die here. */
+./inc/loader/class_ClassLoader.php:273: /* @todo: Do not die here. */
./inc/output.php:11: * @todo We should minimize these includes
./inc/selector.php:11: * @todo We should minimize these includes
./index.php:57: * @todo This method is old code and needs heavy rewrite and should be moved to ApplicationHelper
./application/hub/main/lookup/peer/class_PeerStateLookupTable.php:2:// @DEPRECATED
./application/hub/main/nodes/class_BaseHubNode.php:53: * @deprecated
./application/hub/main/resolver/state/network/class_NetworkStateResolver.php:2:// @DEPRECATED
+./application/hub/main/states/hub/class_BaseHubState.php:2:// @DEPRECATED
./application/hub/main/states/peer/new/class_NewConnectionNodeState.php:2:// @DEPRECATED
./application/hub/main/states/peer/new/class_NewConnectionPeerState.php:2:// @DEPRECATED
+./application/hub/main/states/peer/transport_endpoint/class_TransportEndpointGonePeerState.php:2:// @DEPRECATED
./application/hub/main/streams/package/input/class_PackageInputStream.php:2:// @DEPRECATED
./application/hub/main/streams/package/output/class_PackageOutputStream.php:2:// @DEPRECATED
./application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php:2:// @DEPRECATED
./inc/classes/exceptions/main/class_ClassNotFoundException.php:2:// @DEPRECATED
./inc/classes/exceptions/main/class_ConfigEntryNotFoundException.php:2:// @DEPRECATED
./inc/classes/exceptions/main/class_MissingMethodException.php:14: * @deprecated Please do no longer use this exception
+./inc/classes/exceptions/state/class_InvalidStateException.php:2:// @DEPRECATED
./inc/classes/interfaces/helper/class_HelpableLogin.php:2:// @DEPRECATED
./inc/classes/interfaces/helper/class_HelpableTemplate.php:2:// @DEPRECATED
./inc/classes/main/streams/input/class_BaseInputStream.php:2:// @DEPRECATED