+++ /dev/null
-<?php
-/**
- * A general DHT class
- *
- * @author Roland Haeder <webmaster@shipsimu.org>
- * @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 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 <http://www.gnu.org/licenses/>.
- */
-abstract class BaseDht extends BaseHubSystem implements Distributable {
- /**
- * "Cached" instance of a publish helper
- */
- private $publishHelperInstance = NULL;
-
- /**
- * Stacker name for "INSERT" node data
- */
- const STACKER_NAME_INSERT_NODE = 'dht_insert_node';
- const STACKER_NAME_PENDING_PUBLISHING = 'dht_pending_publish';
-
- /**
- * Protected constructor
- *
- * @param $className Name of the class
- * @return void
- */
- protected function __construct ($className) {
- // Call parent constructor
- parent::__construct($className);
-
- // Get a stacker instance for this DHT
- $stackInstance = ObjectFactory::createObjectByConfiguredName('dht_stacker_class');
-
- // Set it in this class
- $this->setStackInstance($stackInstance);
-
- // Init all stackers
- $this->initStacks();
-
- // Get the state factory and create the initial state.
- DhtStateFactory::createDhtStateInstanceByName('init', $this);
- }
-
- /**
- * Initializes all stackers
- *
- * @return void
- */
- private function initStacks () {
- // Initialize all stacker
- $this->getStackInstance()->initStacks(array(
- self::STACKER_NAME_INSERT_NODE,
- self::STACKER_NAME_PENDING_PUBLISHING,
- ));
- }
-
- /**
- * Registers/updates an entry in the DHT with given data from $dhtData
- * array. Different DHT implemtations may handle this differently as they
- * may enrich the data with more meta data.
- *
- * @param $dhtData A valid array with DHT-related data (e.g. node/peer data)
- * @return void
- */
- protected abstract function insertDataIntoDht (array $dhtData);
-
- /**
- * Updates/refreshes DHT data (e.g. status).
- *
- * @return void
- * @todo Find more to do here
- */
- public function updateDhtData () {
- // Set some dummy configuration entries, e.g. dht_status
- $this->getConfigInstance()->setConfigEntry('dht_status', $this->getStateInstance()->getStateName());
- }
-
- /**
- * Checks whether there are entries in "INSERT" node data stack
- *
- * @return $isPending Whether there are pending entries
- */
- public function ifInsertNodeDataPending () {
- // Determine it if it is not empty
- $isPending = ($this->getStackInstance()->isStackEmpty(self::STACKER_NAME_INSERT_NODE) === FALSE);
-
- // Return status
- return $isPending;
- }
-
- /**
- * Inserts a single entry of node data into the DHT
- *
- * @return void
- */
- public function insertSingleNodeData () {
- // Get next node data from stack
- $nodeData = $this->getStackInstance()->popNamed(self::STACKER_NAME_INSERT_NODE);
-
- // Make sure $nodeData is really an array and has at least one entry
- assert((is_array($nodeData)) && (count($nodeData) > 0));
-
- // Insert the data
- $this->insertDataIntoDht($nodeData);
- }
-
- /**
- * Checks whether there are unpublished entries
- *
- * @return $hasUnpublished Whether there are unpublished entries
- * @todo Add minimum/maximum age limitations
- */
- public function hasUnpublishedEntries () {
- // Call method on database wrapper
- $hasUnpublished = $this->getWrapperInstance()->hasUnpublishedEntries();
-
- // Return it
- return $hasUnpublished;
- }
-
- /**
- * 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
- */
- public function initEntryPublication () {
- // Call method on database wrapper
- $this->getWrapperInstance()->initEntryPublication();
-
- // Get result instance
- $resultInstance = $this->getWrapperInstance()->getUnpublishedEntriesInstance();
-
- // Make sure the result instance is valid
- assert($resultInstance instanceof SearchableResult);
- assert($resultInstance->valid());
-
- // "Walk" through all entries
- while ($resultInstance->next()) {
- // Get current entry
- $current = $resultInstance->current();
-
- // Make sure only valid entries pass
- // @TODO Maybe add more small checks?
- assert(is_array($current));
-
- // ... and push it to the next stack
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('BASE-DHT[' . __METHOD__ . ':' . __LINE__ . '] Pushing entry with ' . count($current) . ' elements to stack ' . self::STACKER_NAME_PENDING_PUBLISHING . ' ...');
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_PENDING_PUBLISHING, $current);
- } // END - while
- }
-
- /**
- * Checks whether there are entries pending publication
- *
- * @return $isPending Whether there are entries pending publication
- */
- public function hasEntriesPendingPublication () {
- // Determine it if it is not empty
- $isPending = ($this->getStackInstance()->isStackEmpty(self::STACKER_NAME_PENDING_PUBLISHING) === FALSE);
-
- // Return status
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('BASE-DHT[' . __METHOD__ . ':' . __LINE__ . '] isPending=' . intval($isPending));
- return $isPending;
- }
-
- /**
- * Whether this DHT's state is 'booting'
- *
- * @return $isBooting Whether this DHT is currently booting
- */
- public function ifDhtIsBooting () {
- // Call state instance
- $isBooting = $this->getStateInstance()->ifDhtIsBooting();
-
- // Return status
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('BASE-DHT[' . __METHOD__ . ':' . __LINE__ . '] isBooting=' . intval($isBooting));
- return $isBooting;
- }
-
- /**
- * Publishes next entry found in stack. This method shall also update the
- * corresponding dabase entry.
- *
- * @return void
- * @todo Find out if loadDescriptorXml() can be called only once to avoid a lot methods working.
- */
- public function publishEntry () {
- // This test must not fail
- assert($this->hasEntriesPendingPublication());
-
- // Is there an instance?
- if (!$this->publishHelperInstance instanceof HelpableDht) {
- // Get a helper instance
- $this->publishHelperInstance = ObjectFactory::createObjectByConfiguredName('dht_publish_entry_helper_class');
- } // END - if
-
- // Load the announcement descriptor
- $this->publishHelperInstance->loadDescriptorXml($this);
-
- // "Pop" next entry
- $entry = $this->getStackInstance()->popNamed(self::STACKER_NAME_PENDING_PUBLISHING);
-
- // Some sanity-checks
- assert(is_array($entry));
-
- // Remove any non-public data the database layer desires
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT[' . __METHOD__ . ':' . __LINE__ . ']: Calling this->getWrapperInstance()->removeNonPublicDataFromArray(data) ...');
- $entry = $this->getWrapperInstance()->removeNonPublicDataFromArray($entry);
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT[' . __METHOD__ . ':' . __LINE__ . ']: entry[]=' . gettype($entry));
-
- // Some sanity-checks again
- assert(is_array($entry));
-
- // Assign multiple variables
- $this->publishHelperInstance->getTemplateInstance()->assignMultipleVariables($entry);
-
- // "Publish" the descriptor by sending it to the bootstrap/list nodes
- $this->publishHelperInstance->sendPackage($this);
- }
-
- /**
- * Whether the DHT has fully bootstrapped (after state 'booting')
- *
- * @return $isFullyBooted Whether the DHT is fully booted
- * @todo 0% done
- */
- public function hasFullyBootstrapped () {
- // Get state and check it
- $this->partialStub('Please implement this method.');
- }
-
- /**
- * Enable DHT bootstrap request acceptance for local node
- *
- * @return void
- * @todo Switch flag 'accept_bootstrap'
- */
- public function enableAcceptDhtBootstrap () {
- // Call method on database wrapper
- $this->getWrapperInstance()->enableAcceptDhtBootstrap();
- }
-}
-
-// [EOF]
-?>