From: Roland Häder Date: Sat, 24 Apr 2010 02:48:48 +0000 (+0000) Subject: New wider interface added, several refacturings: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=b7e4c1ed70bc3fa7f9cfb00071b20ba6002b989f;p=hub.git New wider interface added, several refacturings: - New interface ProtocolHandler added which should be extended by listener and writer interfaces. Please do not implement this interface, we only use it for the socket registry. - BaseListener refactured: Handling of server socket swapped out to new (incomplete) socket registry. - Callback function removed from network package to save a lot (!) memory - New network package target 'upper' added which is an alias for all upper hubs - deliverEnqueuedPackage() basicly finished - Some code cosmetics applied - TODOs.txt updated --- diff --git a/.gitattributes b/.gitattributes index 17550b988..1a0e4f7d4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -42,6 +42,7 @@ application/hub/interfaces/pool/client/.htaccess -text application/hub/interfaces/pool/client/class_PoolableClient.php -text application/hub/interfaces/pool/listener/.htaccess -text application/hub/interfaces/pool/listener/class_PoolableListener.php -text +application/hub/interfaces/protocol/.htaccess -text application/hub/interfaces/query/.htaccess -text application/hub/interfaces/query/class_Queryable.php -text application/hub/interfaces/queues/.htaccess -text diff --git a/application/hub/config.php b/application/hub/config.php index 261a6f7e4..6f485e8f9 100644 --- a/application/hub/config.php +++ b/application/hub/config.php @@ -348,5 +348,8 @@ $cfg->setConfigEntry('raw_package_compressor_class', 'GzipCompressor'); // CFG: HUB-LIST-CLASS $cfg->setConfigEntry('hub_list_class', 'HubList'); +// CFG: SOCKET-REGISTRY-CLASS +$cfg->setConfigEntry('socket_registry_class', 'SocketRegistry'); + // [EOF] ?> diff --git a/application/hub/interfaces/listener/class_Listenable.php b/application/hub/interfaces/listener/class_Listenable.php index 4f3c1892b..ae2aca028 100644 --- a/application/hub/interfaces/listener/class_Listenable.php +++ b/application/hub/interfaces/listener/class_Listenable.php @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -interface Listenable extends FrameworkInterface { +interface Listenable extends ProtocolHandler { /** * Initializes the listener by setting up the required socket server * diff --git a/application/hub/interfaces/package/class_Deliverable.php b/application/hub/interfaces/package/class_Deliverable.php index a3bd1ad73..6f2028d27 100644 --- a/application/hub/interfaces/package/class_Deliverable.php +++ b/application/hub/interfaces/package/class_Deliverable.php @@ -39,11 +39,11 @@ interface Deliverable extends FrameworkInterface { function isPackageEnqueued (); /** - * Delivers an enqueued package to the stated destination. If none is - * provided, the registered helper class is being iterated until no target - * is left. This allows that a single package is being delivered to multiple - * targets without enqueueing it for every target. If no target is provided - * or it can't be determined a NoTargetException is being thrown. + * Delivers an enqueued package to the stated destination. If a non-session + * id is provided, recipient resolver is being asked (and instanced once). + * This allows that a single package is being delivered to multiple targets + * without enqueueing it for every target. If no target is provided or it + * can't be determined a NoTargetException is being thrown. * * @return void * @throws NoTargetException If no target can't be determined diff --git a/application/hub/interfaces/protocol/.htaccess b/application/hub/interfaces/protocol/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/interfaces/protocol/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/interfaces/protocol/class_ProtocolHandler.php b/application/hub/interfaces/protocol/class_ProtocolHandler.php new file mode 100644 index 000000000..ac3d799e9 --- /dev/null +++ b/application/hub/interfaces/protocol/class_ProtocolHandler.php @@ -0,0 +1,28 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 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 . + */ +interface ProtocolHandler extends FrameworkInterface { +} + +// [EOF] +?> diff --git a/application/hub/main/database/wrapper/class_NodeInformationDatabaseWrapper.php b/application/hub/main/database/wrapper/class_NodeInformationDatabaseWrapper.php index 6a736d040..89c57e29a 100644 --- a/application/hub/main/database/wrapper/class_NodeInformationDatabaseWrapper.php +++ b/application/hub/main/database/wrapper/class_NodeInformationDatabaseWrapper.php @@ -36,7 +36,7 @@ class NodeInformationDatabaseWrapper extends BaseDatabaseWrapper { * * @return void */ - protected function __construct() { + protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); } diff --git a/application/hub/main/database/wrapper/class_NodeListDatabaseWrapper.php b/application/hub/main/database/wrapper/class_NodeListDatabaseWrapper.php index 676ad0a5b..d2ce594b7 100644 --- a/application/hub/main/database/wrapper/class_NodeListDatabaseWrapper.php +++ b/application/hub/main/database/wrapper/class_NodeListDatabaseWrapper.php @@ -30,7 +30,7 @@ class NodeListDatabaseWrapper extends BaseDatabaseWrapper { * * @return void */ - protected function __construct() { + protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); } diff --git a/application/hub/main/listener/class_BaseListener.php b/application/hub/main/listener/class_BaseListener.php index 16d79a93a..de796756e 100644 --- a/application/hub/main/listener/class_BaseListener.php +++ b/application/hub/main/listener/class_BaseListener.php @@ -23,7 +23,8 @@ */ class BaseListener extends BaseHubSystem implements Visitable { // Exception code constants - const EXCEPTION_INVALID_SOCKET = 0xa00; + const EXCEPTION_INVALID_SOCKET = 0xa00; + const EXCEPTION_SOCKET_ALREADY_REGISTERED = 0xa01; /** * Used protocol (Default: invalid, which is indeed invalid...) @@ -45,11 +46,6 @@ class BaseListener extends BaseHubSystem implements Visitable { */ private $blockingMode = false; - /** - * Socket resource - */ - private $socketResource = false; - /** * A client pool instance */ @@ -71,6 +67,26 @@ class BaseListener extends BaseHubSystem implements Visitable { parent::__construct($className); } + /** + * Checks wether the given socket resource is a server socket + * + * @param $socketResource A valid socket resource + * @return $isServerSocket Wether the socket resource is a server socket + */ + protected function isServerSocketResource ($socketResource) { + // Check it + $isServerSocket = ((is_resource($socketResource)) && (!@socket_getpeername($socketResource, $peerName))); + + // We need to clear the error here + socket_clear_error($socketResource); + + // Check peer name, it must be empty + $isServerSocket = (($isServerSocket) && (empty($peerName))); + + // Return result + return $isServerSocket; + } + /** * Setter for listen address * @@ -167,25 +183,6 @@ class BaseListener extends BaseHubSystem implements Visitable { return $this->blockingMode; } - /** - * Setter for socket resource - * - * @param $socketResource The socket resource we shall set - * @return void - */ - protected final function setSocketResource ($socketResource) { - $this->socketResource = $socketResource; - } - - /** - * Getter for socket resource - * - * @return $socketResource The socket resource we shall set - */ - public final function getSocketResource () { - return $this->socketResource; - } - /** * Setter for client pool instance * @@ -224,6 +221,66 @@ class BaseListener extends BaseHubSystem implements Visitable { return $this->packageInstance; } + /** + * Registeres the given socket resource for "this" listener instance. This + * will be done in a seperate class to allow package writers to use it + * again. + * + * @param $socketResource A valid server socket resource + * @return void + * @throws InvalidServerSocketException If the given resource is no server socket + * @throws SocketAlreadyRegisteredException If the given resource is already registered + */ + protected function registerServerSocketResource ($socketResource) { + // First check if it is valid + if (!$this->isServerSocketResource($socketResource)) { + // No server socket + throw new InvalidServerSocketException(array($this, $socketResource), self::EXCEPTION_INVALID_SOCKET); + } elseif ($this->isServerSocketRegistered($socketResource)) { + // Already registered + throw new SocketAlreadyRegisteredException($this, self::EXCEPTION_SOCKET_ALREADY_REGISTERED); + } + + // Get a socket registry instance (singleton) + $registryInstance = SocketRegistryFactory::createSocketRegistryInstance(); + + // Register the socket + $registryInstance->registerSocket($this, $socketResource); + } + + /** + * Checks wether given socket resource is registered in socket registry + * + * @param $socketResource A valid server socket resource + * @return $isRegistered Wether given server socket is registered + */ + protected function isServerSocketRegistered ($socketResource) { + // Get a socket registry instance (singleton) + $registryInstance = SocketRegistryFactory::createSocketRegistryInstance(); + + // Check it + $isRegistered = $registryInstance->isSocketRegistered($this, $socketResource); + + // Return result + return $isRegistered; + } + + /** + * Getter for "this" socket resource + * + * @return $socketResource A valid socket resource + */ + public final function getSocketResource () { + // Get a socket registry instance (singleton) + $registryInstance = SocketRegistryFactory::createSocketRegistryInstance(); + + // Get the socket resource + $socketResource = $registryInstance->getSocketResource($this); + + // Return it + return $socketResource; + } + /** * Accepts the visitor to process the visit "request" * diff --git a/application/hub/main/listener/tcp/class_TcpListener.php b/application/hub/main/listener/tcp/class_TcpListener.php index b12e631d5..2e9a54bb3 100644 --- a/application/hub/main/listener/tcp/class_TcpListener.php +++ b/application/hub/main/listener/tcp/class_TcpListener.php @@ -143,7 +143,7 @@ class TcpListener extends BaseListener implements Listenable { } // END - if // Set the main socket - $this->setSocketResource($mainSocket); + $this->registerServerSocketResource($mainSocket); // Initialize the client pool instance $poolInstance = ObjectFactory::createObjectByConfiguredName('client_pool_class', array($this)); diff --git a/application/hub/main/listener/udp/class_UdpListener.php b/application/hub/main/listener/udp/class_UdpListener.php index 866d4c855..6b806ff9d 100644 --- a/application/hub/main/listener/udp/class_UdpListener.php +++ b/application/hub/main/listener/udp/class_UdpListener.php @@ -88,7 +88,7 @@ class UdpListener extends BaseListener implements Listenable { } // END - if // Remember the socket in our class - $this->setSocketResource($socket); + $this->registerServerSocketResource($socket); // Output message $this->debugOutput('LISTENER: UDP listener now ready on IP ' . $this->getListenAddress() . ', port ' . $this->getListenPort() . ' for service.'); diff --git a/application/hub/main/package/class_NetworkPackage.php b/application/hub/main/package/class_NetworkPackage.php index 11aaeff9f..58828e5a0 100644 --- a/application/hub/main/package/class_NetworkPackage.php +++ b/application/hub/main/package/class_NetworkPackage.php @@ -45,6 +45,11 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe */ const STACKER_NAME_UNDECLARED = 'undeclared'; + /** + * Network target (alias): 'upper hubs' + */ + const NETWORK_TARGET_UPPER_HUBS = 'upper'; + /** * Protected constructor * @@ -103,12 +108,11 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe crc32($content) // @TODO Not so good, but needs to be fast! ); - // Now prepare the temporary array and push it on the 'undeclared' stack including a call-back helper instance + // Now prepare the temporary array and push it on the 'undeclared' stack $this->getStackerInstance()->pushNamed(self::STACKER_NAME_UNDECLARED, array( 'sender' => $helperInstance->getNodeInstance()->getSessionId(), - 'recipient' => null, + 'recipient' => self::NETWORK_TARGET_UPPER_HUBS, 'content' => $content, - 'callback' => $helperInstance )); } @@ -126,17 +130,30 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe } /** - * Delivers an enqueued package to the stated destination. If none is - * provided, the registered helper class is being iterated until no target - * is left. This allows that a single package is being delivered to multiple - * targets without enqueueing it for every target. If no target is provided - * or it can't be determined a NoTargetException is being thrown. + * Delivers an enqueued package to the stated destination. If a non-session + * id is provided, recipient resolver is being asked (and instanced once). + * This allows that a single package is being delivered to multiple targets + * without enqueueing it for every target. If no target is provided or it + * can't be determined a NoTargetException is being thrown. * * @return void * @throws NoTargetException If no target can't be determined */ public function deliverEnqueuedPackage () { - $this->partialStub('Please implement this method.'); + // Make sure this method isn't working if there is no package enqueued + if (!$this->isPackageEnqueued()) { + // This is not fatal but should be avoided + // @TODO Add some logging here + return; + } // END - if + + // Now we know for sure there are packages to deliver, we can start + // with the first one. + $packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_UNDECLARED); + die(print_r($packageData, true)); + + // And remove it finally + $this->getStackerInstance()->popNamed(self::STACKER_NAME_UNDECLARED); } } diff --git a/application/hub/main/pools/class_BasePool.php b/application/hub/main/pools/class_BasePool.php index 724540425..7806d07ed 100644 --- a/application/hub/main/pools/class_BasePool.php +++ b/application/hub/main/pools/class_BasePool.php @@ -93,7 +93,7 @@ class BasePool extends BaseHubSystem implements Visitable { $visitorInstance->visitPool($this); // Get a new iterator instance - $iteratorInstance = ObjectFactory::createObjectByConfiguredName($visitorInstance->getVisitorMode() . '_pool_iterator_class', array($this->poolEntriesInstance)); + $iteratorInstance = ObjectFactory::createObjectByConfiguredName($visitorInstance->getVisitorMode() . '_pool_iterator_class', array($this->getPoolEntriesInstance())); // Reset the counter $iteratorInstance->rewind(); diff --git a/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php b/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php index 36c926e3a..ae454ed25 100644 --- a/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php +++ b/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php @@ -60,7 +60,6 @@ class NetworkPackageWriterTask extends BaseTask implements Taskable, Visitable { * Executes the task * * @return void - * @todo 0% */ public function executeTask () { // Get a singleton network package instance diff --git a/docs/TODOs.txt b/docs/TODOs.txt index 7d73c9d27..93aca1a83 100644 --- a/docs/TODOs.txt +++ b/docs/TODOs.txt @@ -24,16 +24,16 @@ ./application/hub/main/iterator/pool/handler/class_HandlerPoolIterator.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:101: * @todo ~50% done ./application/hub/main/listener/udp/class_UdpListener.php:61: * @todo stream_socket_server() was declared slow by some user comments. ./application/hub/main/listener/udp/class_UdpListener.php:62: * @todo Please rewrite it to socket_create() and its brothers. -./application/hub/main/listener/udp/class_UdpListener.php:85: * @todo 0% done ./application/hub/main/lists/class_BaseList.php:264: // @TODO Extend this somehow? ./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/class_BaseHubNode.php:412: * @todo Try to make this method more generic so we can move it in BaseFrameworkSystem -./application/hub/main/nodes/class_BaseHubNode.php:449: * @todo Change the first if() block to check for a specific state -./application/hub/main/nodes/class_BaseHubNode.php:587: // @TODO Add some criteria, e.g. if the node is active or so +./application/hub/main/nodes/class_BaseHubNode.php:420: * @todo Try to make this method more generic so we can move it in BaseFrameworkSystem +./application/hub/main/nodes/class_BaseHubNode.php:457: * @todo Change the first if() block to check for a specific state +./application/hub/main/nodes/class_BaseHubNode.php:595: // @TODO Add some criteria, e.g. if the node is active or so ./application/hub/main/nodes/list/class_HubListNode.php:58: * @todo Implement more bootstrap steps ./application/hub/main/nodes/list/class_HubListNode.php:68: * @todo Unfinished method ./application/hub/main/nodes/list/class_HubListNode.php:91: // @TODO Add some filters here @@ -43,7 +43,8 @@ ./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:103: crc32($content) // @TODO Not so good, but needs to be fast! +./application/hub/main/package/class_NetworkPackage.php:108: crc32($content) // @TODO Not so good, but needs to be fast! +./application/hub/main/package/class_NetworkPackage.php:146: // @TODO Add some logging here ./application/hub/main/package/class_NetworkPackage.php:22: * @todo Needs to add functionality for handling the object's type ./application/hub/main/resolver/state/network/class_NetworkStateResolver.php:67: * @todo ~30% done ./application/hub/main/resolver/state/network/class_NetworkStateResolver.php:76: // @TODO On some systems it is 134, on some 107? @@ -53,10 +54,9 @@ ./application/hub/main/tasks/hub/class_HubSelfConnectTask.php:53: * @todo 0% ./application/hub/main/tasks/hub/ping/class_HubPingTask.php:63: * @todo 0% ./application/hub/main/tasks/hub/update/class_HubUpdateCheckTask.php:53: * @todo 0% -./application/hub/main/tasks/network/class_NetworkPackageWriterTask.php:53: * @todo 0% ./application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php:10: * @todo This template engine does not make use of setTemplateType() ./application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php:256: * @todo Find something useful with this! -./application/hub/main/visitor/tasks/class_ActiveTaskVisitor.php:92: * @todo Does a query needs to perform some actions as an active task? +./application/hub/main/visitor/tasks/class_ActiveTaskVisitor.php:94: * @todo Does a query needs to perform some actions as an active task? ./application/hub/main/visitor/tasks/class_ShutdownTaskVisitor.php:89: * @todo Does a query needs to perform some actions as an active task? ./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