From ca8b7f82b8d488b2a6766ca02fe6de767128be31 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Sun, 13 Feb 2011 15:19:06 +0000 Subject: [PATCH] Introduced package fragmenter class to fragment network packages into smaller chunks --- .gitattributes | 4 ++ application/hub/config.php | 3 ++ application/hub/exceptions.php | 40 ++++++++++++++ .../interfaces/package/class_Deliverable.php | 2 +- .../interfaces/package/fragmenter/.htaccess | 1 + .../package/fragmenter/class_Fragmentable.php | 28 ++++++++++ .../connection/class_BaseConnectionHelper.php | 35 +++++++++--- .../hub/main/package/class_NetworkPackage.php | 20 +++++-- .../hub/main/package/fragmenter/.htaccess | 1 + .../fragmenter/class_PackageFragmenter.php | 53 +++++++++++++++++++ .../class_NetworkPackageWriterTask.php | 2 +- 11 files changed, 175 insertions(+), 14 deletions(-) create mode 100644 application/hub/interfaces/package/fragmenter/.htaccess create mode 100644 application/hub/interfaces/package/fragmenter/class_Fragmentable.php create mode 100644 application/hub/main/package/fragmenter/.htaccess create mode 100644 application/hub/main/package/fragmenter/class_PackageFragmenter.php diff --git a/.gitattributes b/.gitattributes index 35087cf2c..94b2b6a80 100644 --- a/.gitattributes +++ b/.gitattributes @@ -54,6 +54,8 @@ application/hub/interfaces/nodes/.htaccess -text application/hub/interfaces/nodes/class_NodeHelper.php -text svneol=unset#text/plain application/hub/interfaces/package/.htaccess -text application/hub/interfaces/package/class_Deliverable.php -text svneol=unset#text/plain +application/hub/interfaces/package/fragmenter/.htaccess -text +application/hub/interfaces/package/fragmenter/class_Fragmentable.php -text application/hub/interfaces/pool/.htaccess -text application/hub/interfaces/pool/class_Poolable.php -text svneol=unset#text/plain application/hub/interfaces/pool/listener/.htaccess -text @@ -284,6 +286,8 @@ application/hub/main/nodes/regular/.htaccess -text application/hub/main/nodes/regular/class_HubRegularNode.php -text svneol=unset#text/plain application/hub/main/package/.htaccess -text application/hub/main/package/class_NetworkPackage.php -text svneol=unset#text/plain +application/hub/main/package/fragmenter/.htaccess -text +application/hub/main/package/fragmenter/class_PackageFragmenter.php -text application/hub/main/pools/.htaccess -text application/hub/main/pools/class_ -text svneol=unset#text/plain application/hub/main/pools/class_BasePool.php -text svneol=unset#text/plain diff --git a/application/hub/config.php b/application/hub/config.php index 68a1b4890..369f43e9b 100644 --- a/application/hub/config.php +++ b/application/hub/config.php @@ -456,5 +456,8 @@ $cfg->setConfigEntry('session_id', ''); // CFG: EXTERNAL-IP $cfg->setConfigEntry('external_ip', 'free-search.homelinux.org'); +// CFG: PACKAGE-FRAGMENTER-CLASS +$cfg->setConfigEntry('package_fragmenter_class', 'PackageFragmenter'); + // [EOF] ?> diff --git a/application/hub/exceptions.php b/application/hub/exceptions.php index 3e621fa94..62fb49cb9 100644 --- a/application/hub/exceptions.php +++ b/application/hub/exceptions.php @@ -94,8 +94,48 @@ Backtrace: } } +// Error handler +function __errorHandler ($errno, $errstr, $errfile, $errline, array $errcontext) { + // Construct the message + $message = sprintf("File: %s, Line: %s, Code: %s, Message: %s", + basename($errfile), + $errline, + $errno, + $errstr + ); + + // Throw an exception here + throw new FatalErrorException($message, BaseFrameworkSystem::EXCEPTION_FATAL_ERROR); +} // END - function + +// Assertion handler +function __assertHandler ($file, $line, $code) { + // Empty code? + if ($code === '') $code = 'Unknown'; + + // Create message + $message = sprintf("File: %s, Line: %s, Code: %s", + basename($file), + $line, + $code + ); + + // Throw an exception here + throw new AssertionException($message, BaseFrameworkSystem::EXCEPTION_ASSERTION_FAILED); +} // END - function + +// Set error handler +//set_error_handler('__errorHandler'); + // Set the new handler set_exception_handler('hub_exception_handler'); +// Init assert handling +assert_options(ASSERT_ACTIVE, 1); +assert_options(ASSERT_WARNING, 0); +assert_options(ASSERT_BAIL, 0); +assert_options(ASSERT_QUIET_EVAL, 0); +assert_options(ASSERT_CALLBACK, '__assertHandler'); + // [EOF] ?> diff --git a/application/hub/interfaces/package/class_Deliverable.php b/application/hub/interfaces/package/class_Deliverable.php index cdf483346..65c70c4ae 100644 --- a/application/hub/interfaces/package/class_Deliverable.php +++ b/application/hub/interfaces/package/class_Deliverable.php @@ -78,7 +78,7 @@ interface Deliverable extends FrameworkInterface { * * @return void */ - function sentWaitingPackage (); + function sendWaitingPackage (); } // [EOF] diff --git a/application/hub/interfaces/package/fragmenter/.htaccess b/application/hub/interfaces/package/fragmenter/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/interfaces/package/fragmenter/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/interfaces/package/fragmenter/class_Fragmentable.php b/application/hub/interfaces/package/fragmenter/class_Fragmentable.php new file mode 100644 index 000000000..2b72b3a05 --- /dev/null +++ b/application/hub/interfaces/package/fragmenter/class_Fragmentable.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 Fragmentable extends FrameworkInterface { +} + +// [EOF] +?> diff --git a/application/hub/main/helper/connection/class_BaseConnectionHelper.php b/application/hub/main/helper/connection/class_BaseConnectionHelper.php index b2b1d8121..a5d427bde 100644 --- a/application/hub/main/helper/connection/class_BaseConnectionHelper.php +++ b/application/hub/main/helper/connection/class_BaseConnectionHelper.php @@ -131,7 +131,7 @@ class BaseConnectionHelper extends BaseHubHelper implements Registerable, Protoc /** * "Accept" a visitor by simply calling it back * - * @param $visitorInstance A Visitable instance + * @param $visitorInstance A Visitor instance * @return void */ protected final function accept (Visitor $visitorInstance) { @@ -139,25 +139,41 @@ class BaseConnectionHelper extends BaseHubHelper implements Registerable, Protoc $visitorInstance->visitConnectionHelper($this); } + /** + * "Getter" for raw package data from a package array. This method does + * honor any unsend bytes in the back-buffer and the sending buffer size. + * + * @param $packageData Raw package data array + * @return $rawData Raw package data bytes + */ + private function getRawDataFromPackageArray (array $packageData) { + // Get the fragmenter instance + $fragmenterInstance = ObjectFactory::createObjectByConfiguredName('package_fragmenter_class'); + $fragmenterInstance->debugInstance(); + + // Return it + return $rawData; + } + /** * Sends raw package data to the recipient * * @param $packageData Raw package data - * @return void - *@ throws InvalidSocketException If we got a problem with this socket + * @return $sentBytes Actual sent bytes to the peer + * @throws InvalidSocketException If we got a problem with this socket */ public function sendRawPackageData (array $packageData) { // We need to "package" all data. This is done by a implode() - $rawData = implode(NetworkPackage::PACKAGE_DATA_SEPERATOR, $packageData); + $rawData = $this->getRawDataFromPackageArray($packageData); // Get socket resource $socketResource = $this->getSocketResource(); // And deliver it - $numBytes = @socket_write($socketResource, $rawData, $this->getConfigInstance()->getConfigEntry($this->getProtocol() . '_buffer_length') - $this->offset); + $sentBytes = @socket_write($socketResource, $rawData, $this->getConfigInstance()->getConfigEntry($this->getProtocol() . '_buffer_length') - $this->offset); // If there was an error, we don't continue here - if ($numBytes === false) { + if ($sentBytes === false) { // Get socket error code for verification $socketError = socket_last_error($socketResource); @@ -171,8 +187,11 @@ class BaseConnectionHelper extends BaseHubHelper implements Registerable, Protoc throw new InvalidSocketException(array($this, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); } // END - if - // How much has been sent? - die('num=' . $numBytes . "\n"); + // The difference between sent bytes and length of raw data should not be below zero + assert((strlen($rawData) - $sentBytes) >= 0); + + // Return sent bytes + return $sentBytes; } /** diff --git a/application/hub/main/package/class_NetworkPackage.php b/application/hub/main/package/class_NetworkPackage.php index dd634f3ad..323dba060 100644 --- a/application/hub/main/package/class_NetworkPackage.php +++ b/application/hub/main/package/class_NetworkPackage.php @@ -89,6 +89,11 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe */ const STACKER_NAME_OUTGOING = 'outgoing'; + /** + * Stacker name for "back-buffered" packages + */ + const STACKER_NAME_BACK_BUFFER = 'backbuffer'; + /** * Network target (alias): 'upper hubs' */ @@ -256,7 +261,10 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe } // END - if // Sent it away (we catch exceptions one method above - $connectionInstance->sendRawPackageData($packageData); + $sentBytes = $connectionInstance->sendRawPackageData($packageData); + + // Remember unsent raw bytes in back-buffer, if any + $this->storeUnsentBytesInBackBuffer($packageData, $sentBytes); } /** @@ -391,7 +399,10 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe * * @return void */ - public function sentWaitingPackage () { + public function sendWaitingPackage () { + // Sent any waiting bytes in the back-buffer + $this->sendBackBufferBytes(); + // Sanity check if we have packages waiting for delivery if (!$this->isPackageWaitingDelivery()) { // This is not fatal but should be avoided @@ -402,11 +413,12 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe // Get the package again $packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_OUTGOING); - // Now try to send it try { + // Now try to send it $this->sendOutgoingPackage($packageData); + die("O!\n"); - // And remove it finally when it has been fully delivered + // And remove it finally $this->getStackerInstance()->popNamed(self::STACKER_NAME_OUTGOING); } catch (InvalidSocketException $e) { // Output exception message diff --git a/application/hub/main/package/fragmenter/.htaccess b/application/hub/main/package/fragmenter/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/package/fragmenter/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/package/fragmenter/class_PackageFragmenter.php b/application/hub/main/package/fragmenter/class_PackageFragmenter.php new file mode 100644 index 000000000..f19ac2528 --- /dev/null +++ b/application/hub/main/package/fragmenter/class_PackageFragmenter.php @@ -0,0 +1,53 @@ + + * @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 . + */ +class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates an instance of this class + * + * @return $fragmenterInstance An instance of a Fragmentable class + */ + public final static function createPackageFragmenter () { + // Get new instance + $fragmenterInstance = new PackageFragmenter(); + + // Return the prepared instance + return $fragmenterInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php b/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php index 15b974f96..946cf77bd 100644 --- a/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php +++ b/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php @@ -74,7 +74,7 @@ class NetworkPackageWriterTask extends BaseTask implements Taskable, Visitable { $packageInstance->deliverDeclaredPackage(); } elseif ($packageInstance->isPackageWaitingDelivery()) { // Sent it finally out - $packageInstance->sentWaitingPackage(); + $packageInstance->sendWaitingPackage(); } } } -- 2.39.2