From 9519de183e0b56acbc28d2d2c5b11537d6888658 Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Tue, 3 Feb 2015 18:24:12 +0100 Subject: [PATCH] Added profile option to check_reload_status (configd), measured framework overhead, current max processing for the daemon is about 6200 req/s on my macbook. ( limited by socket.accept, if needed we could implement another dispatch method in the future) Simple implementation to use the backend service from the frontend implemented. --- .../OPNsense/Base/ControllerBase.php | 6 +- .../OPNsense/Base/IndexController.php | 4 +- .../OPNsense/Sample/PageController.php | 2 + .../app/models/OPNsense/Base/BaseModel.php | 4 + .../mvc/app/models/OPNsense/Core/Backend.php | 78 +++++++++++++++++++ src/opnsense/service/check_reload_status.py | 21 ++++- 6 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 src/opnsense/mvc/app/models/OPNsense/Core/Backend.php diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php b/src/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php index 6f5094737..0a810a802 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php @@ -29,6 +29,7 @@ namespace OPNsense\Base; use Phalcon\Mvc\Controller; + use Phalcon\Translate\Adapter\NativeArray; /** @@ -39,14 +40,13 @@ class ControllerBase extends Controller { /** * translate a text - * @param string $tag input text - * @return string + * @return NativeArray */ public function getTranslator() { // TODO: implement language service $messages = array(); - return new \Phalcon\Translate\Adapter\NativeArray(array( + return new NativeArray(array( "content" => $messages )); diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Base/IndexController.php b/src/opnsense/mvc/app/controllers/OPNsense/Base/IndexController.php index 3a31c51db..2369bcd5f 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Base/IndexController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Base/IndexController.php @@ -32,12 +32,10 @@ namespace OPNsense\Base; * Class IndexController * @package OPNsense\Base */ -class IndexController extends \OPNsense\Base\ControllerBase +class IndexController extends ControllerBase { public function indexAction() { -// $this->view->title = $this->request->getURI(); -// $this->view->pick('OPNsense/Sample/index'); } } diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Sample/PageController.php b/src/opnsense/mvc/app/controllers/OPNsense/Sample/PageController.php index 1b0ff1491..09a07d4d7 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Sample/PageController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Sample/PageController.php @@ -66,6 +66,7 @@ class PageController extends ControllerBase /** * controller for sample index page, defaults to http:///sample/page + * @param array $error_msg error messages */ public function indexAction($error_msg = array()) { @@ -147,5 +148,6 @@ class PageController extends ControllerBase "action" => "index" )); + return true; } } diff --git a/src/opnsense/mvc/app/models/OPNsense/Base/BaseModel.php b/src/opnsense/mvc/app/models/OPNsense/Base/BaseModel.php index 173c1b832..fd290549f 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Base/BaseModel.php +++ b/src/opnsense/mvc/app/models/OPNsense/Base/BaseModel.php @@ -131,20 +131,24 @@ abstract class BaseModel if ($config_section_data != null) { $counter = 0 ; foreach ($config_section_data as $conf_section) { + // iterate array items from config data $child_node = new ContainerField($fieldObject->__reference . "." . ($counter++), $tagName); $this->parseXml($xmlNode, $conf_section, $child_node); $fieldObject->addChildNode(null, $child_node); } } else { + // There's no content in config.xml for this array node. $child_node = new ContainerField($fieldObject->__reference . ".0", $tagName); $child_node->setInternalIsVirtual(); $this->parseXml($xmlNode, $config_section_data, $child_node); $fieldObject->addChildNode(null, $child_node); } } else { + // All other node types (Text,Email,...) $this->parseXml($xmlNode, $config_section_data, $fieldObject); } + // add object as child to this node $internal_data->addChildNode($xmlNode->getName(), $fieldObject); } diff --git a/src/opnsense/mvc/app/models/OPNsense/Core/Backend.php b/src/opnsense/mvc/app/models/OPNsense/Core/Backend.php new file mode 100644 index 000000000..e6b9ac722 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Core/Backend.php @@ -0,0 +1,78 @@ +stream = null; + } + + /** + * send event to backend + * @param $event event string + * @param int $timeout timeout in seconds + * @return string + * @throws \Exception + */ + public function sendEvent($event, $timeout = 60) + { + $stream = stream_socket_client('unix://'.$this->configdSocket, $errorNumber, $errorMessage, $timeout); + if ($stream === false) { + throw new \Exception("Failed to connect: $errorMessage"); + } + + stream_set_timeout($stream, $timeout); + fwrite($stream, $event); + $resp = stream_get_contents($stream); + $info = stream_get_meta_data($stream); + + if ($info['timed_out'] == 1) { + throw new \Exception("Timeout (".$timeout.") executing :".$event); + } + + return $resp; + } + +} diff --git a/src/opnsense/service/check_reload_status.py b/src/opnsense/service/check_reload_status.py index 0fe04bb05..a1b6decf8 100755 --- a/src/opnsense/service/check_reload_status.py +++ b/src/opnsense/service/check_reload_status.py @@ -42,7 +42,7 @@ import sys import ConfigParser import modules.processhandler from modules.daemonize import Daemonize - +import cProfile, pstats # find program path if len(__file__.split('/')[:-1]) >0 : @@ -73,7 +73,24 @@ else: if len(sys.argv) > 1 and 'console' in sys.argv[1:]: print('run %s in console mode'%sys.argv[0]) - proc_handler.run() + if 'profile' in sys.argv[1:]: + # profile configd + # for graphical output use gprof2dot: + # gprof2dot -f pstats /tmp/configd.profile -o /tmp/callingGraph.dot + # (https://code.google.com/p/jrfonseca/wiki/Gprof2Dot) + print ("... to stop profiling") + profile = cProfile.Profile() + profile.enable() + try: + proc_handler.run() + except KeyboardInterrupt: + pass + except: + raise + profile.disable() + profile.dump_stats('/tmp/configd.profile') + else: + proc_handler.run() else: # daemonize process daemon = Daemonize(app=__file__.split('/')[-1].split('.py')[0], pid=cnf.get('main','pid_filename'), action=proc_handler.run)