From 8f21caa3cca5ee6e4f4a6f786c50851a4d3cc559 Mon Sep 17 00:00:00 2001 From: Roland Haeder Date: Sat, 15 Feb 2014 19:57:09 +0100 Subject: [PATCH] Continued with hub development: - Added specialized interface DistributableNode for DHTs for nodes - Moved some node-related methods to above new interface - DHT recipient discovery is not yet fully implemented as it will find first X (10 by default) in the DHT and return them. This is a bad idea as it will exclude many other relevant nodes. So this is a very early stage. Signed-off-by: Roland Haeder --- application/hub/config.php | 3 + .../distributable/class_Distributable.php | 68 ++--------- .../interfaces/distributable/node/.htaccess | 1 + .../node/class_DistributableNode.php | 111 ++++++++++++++++++ .../wrapper/class_NodeDhtWrapper.php | 23 +++- ...odeDistributedHashTableDatabaseWrapper.php | 23 ++++ .../hub/main/dht/node/class_NodeDhtFacade.php | 36 ++++++ .../dht/class_DhtRecipientDiscovery.php | 13 +- .../factories/dht/class_DhtObjectFactory.php | 11 +- .../main/recipient/dht/class_DhtRecipient.php | 2 +- 10 files changed, 220 insertions(+), 71 deletions(-) create mode 100644 application/hub/interfaces/distributable/node/.htaccess create mode 100644 application/hub/interfaces/distributable/node/class_DistributableNode.php diff --git a/application/hub/config.php b/application/hub/config.php index 316f6188d..34f9ca406 100644 --- a/application/hub/config.php +++ b/application/hub/config.php @@ -764,6 +764,9 @@ $cfg->setConfigEntry('package_recipient_max_count', 3); // CFG: NODE-DHT-CLASS $cfg->setConfigEntry('node_dht_class', 'NodeDhtFacade'); +// CFG: MAX-DHT-RECIPIENTS +$cfg->setConfigEntry('max_dht_recipients', 10); + /////////////////////////////////////////////////////////////////////////////// // Node states /////////////////////////////////////////////////////////////////////////////// diff --git a/application/hub/interfaces/distributable/class_Distributable.php b/application/hub/interfaces/distributable/class_Distributable.php index 43e7bd85d..81a85c3a6 100644 --- a/application/hub/interfaces/distributable/class_Distributable.php +++ b/application/hub/interfaces/distributable/class_Distributable.php @@ -38,52 +38,6 @@ interface Distributable extends FrameworkInterface { */ function bootstrapDht (); - /** - * Finds a node locally by given session id - * - * @param $sessionId Session id to lookup - * @return $nodeData Node-data array - */ - function findNodeLocalBySessionId ($sessionId); - - /** - * Registers an other node with this node by given message data. The - * following data must always be present: - * - * - session-id (for finding the node's record together with below data) - * - external-ip (hostname or IP number) - * - listen-port (TCP/UDP listen port for inbound connections) - * - * @param $messageData An array with all minimum message data - * @param $handlerInstance An instance of a Handleable class - * @param $forceUpdate Optionally force update, don't register (default: register if not found) - * @return void - */ - function registerNodeByMessageData (array $messageData, Handleable $handlerInstance, $forceUpdate = FALSE); - - /** - * Queries the local DHT data(base) for a node list with all supported - * object types except the node by given session id. - * - * @param $messageData An array with message data from a node_list request - * @param $handlerInstance An instance of a Handleable class - * @param $excludeKey Array key which should be excluded - * @param $andKey Array of $separator-separated list of elements which all must match - * @param $separator Sepator char (1st parameter for explode() call) - * @return $nodeList An array with all found nodes - */ - function queryLocalNodeListExceptByMessageData (array $messageData, Handleable $handlerInstance, $excludeKey, $andKey, $separator); - - /** - * Inserts given node list array (from earlier database result produced by - * an other node) into the DHT. This array origins from above method - * queryLocalNodeListExceptByMessageData(). - * - * @param $nodeList An array from an earlier database result instance - * @return void - */ - function insertNodeList (array $nodeList); - /** * Updates/refreshes DHT data (e.g. status). * @@ -91,20 +45,6 @@ interface Distributable extends FrameworkInterface { */ function updateDhtData (); - /** - * Checks whether there are entries in "INSERT" node data stack - * - * @return $isPending Whether there are pending entries - */ - function ifInsertNodeDataPending (); - - /** - * Inserts a single entry of node data into the DHT - * - * @return void - */ - function insertSingleNodeData (); - /** * Checks whether there are unpublished entries * @@ -135,6 +75,14 @@ interface Distributable extends FrameworkInterface { * @return void */ function publishEntry (); + + /** + * Find recipients for given package data + * + * @param $packageData An array of valid package data + * @return $recipients An indexed array with DHT recipients + */ + function findRecipientsByPackageData (array $packageData); } // [EOF] diff --git a/application/hub/interfaces/distributable/node/.htaccess b/application/hub/interfaces/distributable/node/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/interfaces/distributable/node/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/interfaces/distributable/node/class_DistributableNode.php b/application/hub/interfaces/distributable/node/class_DistributableNode.php new file mode 100644 index 000000000..c44bc463c --- /dev/null +++ b/application/hub/interfaces/distributable/node/class_DistributableNode.php @@ -0,0 +1,111 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.shipsimu.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 DistributableNode extends Distributable { + /** + * Finds a node locally by given session id + * + * @param $sessionId Session id to lookup + * @return $nodeData Node-data array + */ + function findNodeLocalBySessionId ($sessionId); + + /** + * Registers an other node with this node by given message data. The + * following data must always be present: + * + * - session-id (for finding the node's record together with below data) + * - external-ip (hostname or IP number) + * - listen-port (TCP/UDP listen port for inbound connections) + * + * @param $messageData An array with all minimum message data + * @param $handlerInstance An instance of a Handleable class + * @param $forceUpdate Optionally force update, don't register (default: register if not found) + * @return void + */ + function registerNodeByMessageData (array $messageData, Handleable $handlerInstance, $forceUpdate = FALSE); + + /** + * Queries the local DHT data(base) for a node list with all supported + * object types except the node by given session id. + * + * @param $messageData An array with message data from a node_list request + * @param $handlerInstance An instance of a Handleable class + * @param $excludeKey Array key which should be excluded + * @param $andKey Array of $separator-separated list of elements which all must match + * @param $separator Sepator char (1st parameter for explode() call) + * @return $nodeList An array with all found nodes + */ + function queryLocalNodeListExceptByMessageData (array $messageData, Handleable $handlerInstance, $excludeKey, $andKey, $separator); + + /** + * Inserts given node list array (from earlier database result produced by + * an other node) into the DHT. This array origins from above method + * queryLocalNodeListExceptByMessageData(). + * + * @param $nodeList An array from an earlier database result instance + * @return void + */ + function insertNodeList (array $nodeList); + + /** + * Checks whether there are entries in "INSERT" node data stack + * + * @return $isPending Whether there are pending entries + */ + function ifInsertNodeDataPending (); + + /** + * Checks whether there are unpublished entries + * + * @return $hasUnpublished Whether there are unpublished entries + */ + function hasUnpublishedEntries (); + + /** + * Initializes publication of DHT entries. This does only prepare + * publication. The next step is to pickup such prepared entries and publish + * them by uploading to other (recently appeared) DHT members. + * + * @return void + */ + function initEntryPublication (); + + /** + * Checks whether there are entries pending publication + * + * @return $isPending Whether there are entries pending publication + */ + function hasEntriesPendingPublication (); + + /** + * Publishes next entry found in stack. This method shall also update the + * corresponding dabase entry. + * + * @return void + */ + function publishEntry (); +} + +// [EOF] +?> diff --git a/application/hub/interfaces/wrapper/class_NodeDhtWrapper.php b/application/hub/interfaces/wrapper/class_NodeDhtWrapper.php index 64eea8695..938a3189f 100644 --- a/application/hub/interfaces/wrapper/class_NodeDhtWrapper.php +++ b/application/hub/interfaces/wrapper/class_NodeDhtWrapper.php @@ -22,6 +22,13 @@ * along with this program. If not, see . */ interface NodeDhtWrapper extends DatabaseWrapper { + /** + * Static getter for an array of all DHT database entries + * + * @return $elements All elements for the DHT dabase + */ + static function getAllElements (); + /** * Getter for result instance for unpublished entries * @@ -127,12 +134,20 @@ interface NodeDhtWrapper extends DatabaseWrapper { function initEntryPublication (); /** - * Removes non-public data from given array. + * Removes non-data from given array. + * + * @param $data An array with possible non-data that needs to be removed. + * @return $data A cleaned up array with only data. + */ + function removeNonPublicDataFromArray(array $data); + + /** + * Find recipients for given package data and returns it as a result instance * - * @param $data An array with possible non-public data that needs to be removed. - * @return $data A cleaned up array with only public data. + * @param $packageData An array of valid package data + * @return $recipients An indexed array with DHT recipients */ - function removeNonPublicDataFromArray (array $data); + function getResultFromExcludedSender (array $packageData); } // [EOF] diff --git a/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php b/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php index c86ec861b..a51fc2cb1 100644 --- a/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php +++ b/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php @@ -507,6 +507,29 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem // Return cleaned data return $data; } + + /** + * Find recipients for given package data and exclude the sender + * + * @param $packageData An array of valid package data + * @return $recipients An indexed array with DHT recipients + */ + public function getResultFromExcludedSender (array $packageData) { + // Assert on required array field + assert(isset($packageData[NetworkPackage::PACKAGE_DATA_SENDER])); + + // First creata a search instance + $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); + + // Then exclude 'sender' field as the sender is the current (*this*) node + $searchInstance->addExcludeCriteria(NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_SESSION_ID, $packageData[NetworkPackage::PACKAGE_DATA_SENDER]); + + // Get a result instance back from DHT database wrapper. + $resultInstance = $this->doSelectByCriteria($searchInstance); + + // Return result instance + return $resultInstance; + } } // [EOF] diff --git a/application/hub/main/dht/node/class_NodeDhtFacade.php b/application/hub/main/dht/node/class_NodeDhtFacade.php index 7b6535cda..c9017ec7e 100644 --- a/application/hub/main/dht/node/class_NodeDhtFacade.php +++ b/application/hub/main/dht/node/class_NodeDhtFacade.php @@ -302,6 +302,42 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable { $this->getStackerInstance()->pushNamed(self::STACKER_NAME_INSERT_NODE, $nodeData); } // END - foreach } + + /** + * Find recipients for given package data + * + * @param $packageData An array of valid package data + * @return $recipients An indexed array with DHT recipients + */ + public function findRecipientsByPackageData (array $packageData) { + // Get max recipients + $maxRecipients = $this->getConfigInstance()->getConfigEntry('max_dht_recipients'); + + // Query get a result instance back from DHT database wrapper. + $resultInstance = $this->getWrapperInstance()->getResultFromExcludedSender($packageData); + + // Init array + $recipients = array(); + + // Search for all recipients + while ($resultInstance->next()) { + // Get current entry + $current = $resultInstance->current(); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE[' . __LINE__ . ']: current=' . print_r($current, TRUE)); + + // Add instance to recipient list + array_push($recipients, $current); + + // Has the maximum been reached? + if (count($recipients) == $maxRecipients) { + // Stop search here + break; + } // END - if + } // END - while + + // Return filled array + return $recipients; + } } // [EOF] diff --git a/application/hub/main/discovery/dht/class_DhtRecipientDiscovery.php b/application/hub/main/discovery/dht/class_DhtRecipientDiscovery.php index 3ca916f90..f9c2a4630 100644 --- a/application/hub/main/discovery/dht/class_DhtRecipientDiscovery.php +++ b/application/hub/main/discovery/dht/class_DhtRecipientDiscovery.php @@ -41,6 +41,12 @@ class DhtRecipientDiscovery extends BaseNodeDiscovery implements DiscoverableDht // Get an instance of this class $discoveryInstance = new DhtRecipientDiscovery(); + // Get a DHT instance + $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + + // Set it here + $discoveryInstance->setDhtInstance($dhtInstance); + // Return the prepared instance return $discoveryInstance; } @@ -50,10 +56,13 @@ class DhtRecipientDiscovery extends BaseNodeDiscovery implements DiscoverableDht * * @param $packageData Valid package data array * @return $recipients An indexed array with DHT recipients - * @todo 0% done */ public function resolveRecipientsByPackageData (array $packageData) { - $this->partialStub('Please implement this method. packageData[]=' . print_r($packageData, TRUE)); + // Use facade to get recipients back + $recipients = $this->getDhtInstance()->findRecipientsByPackageData($packageData); + + // Return it + return $recipients; } } diff --git a/application/hub/main/factories/dht/class_DhtObjectFactory.php b/application/hub/main/factories/dht/class_DhtObjectFactory.php index a7355218e..4c7ff621f 100644 --- a/application/hub/main/factories/dht/class_DhtObjectFactory.php +++ b/application/hub/main/factories/dht/class_DhtObjectFactory.php @@ -39,16 +39,19 @@ class DhtObjectFactory extends ObjectFactory { * @return $dhtInstance An instance of a DHT object class */ public static final function createDhtObjectInstance ($prefix) { + // Set instance name + $name = $prefix . '_dht'; + // If there is no handler? - if (Registry::getRegistry()->instanceExists($prefix . '_dht')) { + if (Registry::getRegistry()->instanceExists($name)) { // Get handler from registry - $dhtInstance = Registry::getRegistry()->getInstance($prefix . '_dht'); + $dhtInstance = Registry::getRegistry()->getInstance($name); } else { // Get the handler instance - $dhtInstance = self::createObjectByConfiguredName($prefix . '_dht_class'); + $dhtInstance = self::createObjectByConfiguredName($name . '_class'); // Add it to the registry - Registry::getRegistry()->addInstance($prefix . '_dht', $dhtInstance); + Registry::getRegistry()->addInstance($name, $dhtInstance); } // Return the instance diff --git a/application/hub/main/recipient/dht/class_DhtRecipient.php b/application/hub/main/recipient/dht/class_DhtRecipient.php index 2e32f8158..1f0bd9d33 100644 --- a/application/hub/main/recipient/dht/class_DhtRecipient.php +++ b/application/hub/main/recipient/dht/class_DhtRecipient.php @@ -56,7 +56,7 @@ class DhtRecipient extends BaseRecipient implements Recipient { * @param $packageData Valid package data array * @return void * @throws FrameworkException Could throw different exceptions depending on implementation - * @todo 0% done + * @todo 30% done */ public function resolveRecipient ($recipient, Listable $listInstance, array $packageData) { // Make sure the recipient is valid -- 2.39.5