Commit 78690c68 authored by Pavel Vainerman's avatar Pavel Vainerman

Добавил тест для измерения скорости рабты с очередью сообщений

parent 6d66ffdb
......@@ -432,6 +432,7 @@ AC_CONFIG_FILES([Makefile
extensions/tests/Makefile
extensions/tests/SMemoryTest/Makefile
extensions/tests/MBSlaveTest/Makefile
extensions/tests/MQPerfTest/Makefile
testsuite/Makefile
python/lib/Makefile
python/lib/pyUniSet/Makefile
......
noinst_PROGRAMS = mq-test
mq_test_LDADD = $(top_builddir)/lib/libUniSet2.la $(SIGC_LIBS) $(COMCPP_LIBS)
mq_test_CPPFLAGS = -I$(top_builddir)/include -I$(top_builddir)/extensions/include $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
mq_test_SOURCES = TestProc_SK.cc TestProc.cc mq-test.cc
BUILT_SOURCES=TestProc_SK.cc TestProc_SK.h
TestProc_SK.cc TestProc_SK.h: testproc.src.xml
$(top_builddir)/Utilities/codegen/@PACKAGE@-codegen -l $(top_builddir)/Utilities/codegen --ask -n TestProc --local-include --topdir $(top_builddir)/ --no-main testproc.src.xml
clean-local:
rm -rf *_SK.cc *_SK.h
#include <iomanip>
#include "Exceptions.h"
#include "TestProc.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -----------------------------------------------------------------------------
TestProc::TestProc( UniSetTypes::ObjectId id, xmlNode* confnode ):
TestProc_SK( id, confnode )
{
}
// -----------------------------------------------------------------------------
TestProc::~TestProc()
{
}
// -----------------------------------------------------------------------------
bool TestProc::isFullQueue()
{
return ( getCountOfQueueFull() > 0 );
}
// -----------------------------------------------------------------------------
TestProc::TestProc()
{
cerr << ": init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
#ifndef TestProc_H_
#define TestProc_H_
// -----------------------------------------------------------------------------
#include "TestProc_SK.h"
// -----------------------------------------------------------------------------
class TestProc:
public TestProc_SK
{
public:
TestProc( UniSetTypes::ObjectId id, xmlNode* confnode );
virtual ~TestProc();
bool isFullQueue();
protected:
TestProc();
private:
};
// -----------------------------------------------------------------------------
#endif // TestProc_H_
// -----------------------------------------------------------------------------
#include <string>
#include "UniSetActivator.h"
#include "Extensions.h"
#include "UHelpers.h"
#include "TestProc.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// --------------------------------------------------------------------------
int main(int argc, const char** argv)
{
try
{
auto conf = uniset_init(argc, argv);
auto act = UniSetActivator::Instance();
auto tp = UniSetTypes::make_object<TestProc>("TestProc1", "TestProc");
act->add(tp);
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(true);
SensorMessage smsg(100,2);
TransportMessage tm( std::move(smsg.transport_msg()) );
size_t num = 0;
const size_t max = 100000;
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
for( num=0; num<max; num++ )
{
tp->push(tm);
if( tp->isFullQueue() )
break;
if( num%100 == 0 )
msleep(50);
}
end = std::chrono::system_clock::now();
int elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cerr << "elapsed time: " << elapsed_seconds << " ms num=" << num << endl;
std::cerr << "speed: " << ((float)elapsed_seconds / num) << " msg per sec" << endl;
return 0;
}
catch( const SystemError& err )
{
cerr << "(mq-test): " << err << endl;
}
catch( const Exception& ex )
{
cerr << "(mq-test): " << ex << endl;
}
catch( const std::exception& e )
{
cerr << "(mq-test): " << e.what() << endl;
}
catch(...)
{
cerr << "(mq-test): catch(...)" << endl;
}
return 1;
}
#!/bin/sh
START=uniset2-start.sh
${START} -f ./mq-test --confile ./test.xml $*
../../../Utilities/scripts/uniset2-stop.sh
\ No newline at end of file
../../../conf/test.xml
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
name - название класса
msgcount - сколько сообщений обрабатывается за один раз
sleep_msec - пауза между итерациями в работе процесса
type
====
in - входные регистры (только для чтения)
out - выходные регистры (запись)
-->
<TestProc>
<settings>
<set name="class-name" val="TestProc"/>
<set name="msg-count" val="30"/>
<set name="sleep-msec" val="20"/>
</settings>
<variables>
</variables>
<smap>
</smap>
<msgmap>
</msgmap>
</TestProc>
../../../Utilities/scripts/uniset2-functions.sh
\ No newline at end of file
SUBDIRS=SMemoryTest MBSlaveTest
SUBDIRS=SMemoryTest MBSlaveTest MQPerfTest
if HAVE_TESTS
noinst_PROGRAMS = tests tests_with_conf tests_with_sm sm_perf_test
......
/*
* Copyright (c) 2015 Pavel Vainerman.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, version 2.1.
*
* 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
* Lesser General Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// --------------------------------------------------------------------------
#ifndef UHelpers_H_
#define UHelpers_H_
// --------------------------------------------------------------------------
#include "UniSetTypes.h"
#include "Configuration.h"
// --------------------------------------------------------------------------
namespace UniSetTypes
{
// Шаблон для "универсальной инициализации объекта(процесса)".
// Использование:
// auto m = make_object<MyClass>("ObjectId","secname");
// --
// Где MyClass должен содержать конструктор MyClass( const ObjetctId id, xmlNode* cnode, ...any args.. );
// ---------------
// Если secname задан, то ищется: <secname name="ObjectId" ....>
// Если secname не задан, то: <idname name="idname" ...>
//----------------
template<typename T, typename... _Args>
std::shared_ptr<T> make_object( const std::string& idname, const std::string& secname, _Args&&... __args )
{
auto conf = UniSetTypes::uniset_conf();
UniSetTypes::ObjectId id = conf->getObjectID(idname);
if( id == UniSetTypes::DefaultObjectId )
throw UniSetTypes::SystemError("(make_object<" + string(typeid(T).name()) + ">): Not found ID for '" + idname + "'");
auto xml = conf->getConfXML();
std::string s( (secname.empty() ? idname : secname) );
xmlNode* cnode = conf->findNode(xml->getFirstNode(),s,idname);
if( cnode == 0 )
throw UniSetTypes::SystemError("(make_object<" + string(typeid(T).name()) + ">): Not found xmlnode <" + s + " name='" + idname + "' ... >");
std::shared_ptr<T> obj =std::make_shared<T>(id,cnode,std::forward<_Args>(__args)...);
if (obj == nullptr)
throw UniSetTypes::SystemError("(make_object<T> == nullptr" + string(typeid(T).name()));
return obj;
}
// -----------------------------------------------------------------------------
// версия с указанием начального xml-узла, с которого ведётся поиск xmlNode
// а ID берётся из поля name="" у найденного xmlnode.
template<typename T, typename... _Args>
std::shared_ptr<T> make_object_x( xmlNode* root, const std::string& secname, _Args&&... __args )
{
auto conf = UniSetTypes::uniset_conf();
auto xml = conf->getConfXML();
xmlNode* cnode = conf->findNode(root,secname,"");
if( cnode == 0 )
throw UniSetTypes::SystemError("(make_object_x<" + string(typeid(T).name()) + ">): Not found xmlnode <" + secname + " ... >");
string idname = conf->getProp(cnode,"name");
UniSetTypes::ObjectId id = conf->getObjectID(idname);
if( id == UniSetTypes::DefaultObjectId )
throw UniSetTypes::SystemError("(make_object_x<" + string(typeid(T).name()) + ">): Not found ID for '" + idname + "'");
return std::make_shared<T>(id,cnode,std::forward<_Args>(__args)...);
}
// -----------------------------------------------------------------------------
// Просто обёртка для удобства вывода сообщений об ошибке в лог "объекта"..
// "по задумке" позволяет не загромаждать код..
// T - тип создаваемого объекта
// M - (master) - класс который создаёт объект (подразумевается, что он UniSetManager)
template<typename T, typename M, typename... _Args>
std::shared_ptr<T> make_child_object( M* m, const std::string& idname, const std::string& secname, _Args&&... __args )
{
try
{
m->log()->info() << m->getName() << "(" << __FUNCTION__ << "): " << "create " << idname << "..." << std::endl;
auto o = UniSetTypes::make_object<T>(idname,secname,std::forward<_Args>(__args)...);
m->add(o);
m->logAgregator()->add(o->logAgregator());
return std::move(o);
}
catch( const UniSetTypes::Exception& ex )
{
m->log()->crit() << m->getName() << "(" << __FUNCTION__ << "): " << "(create " << idname << "): " << ex << std::endl;
throw;
}
}
// -----------------------------------------------------------------------------
// Версия использующая make_object_x<>
template<typename T, typename M, typename... _Args>
std::shared_ptr<T> make_child_object_x( M* m, xmlNode* root, const std::string& secname, _Args&&... __args )
{
try
{
auto o = UniSetTypes::make_object_x<T>(root,secname,std::forward<_Args>(__args)...);
m->add(o);
m->logAgregator()->add(o->logAgregator());
return std::move(o);
}
catch( const UniSetTypes::Exception& ex )
{
m->log()->crit() << m->getName() << "(" << __FUNCTION__ << "): " << "(create " << string(typeid(T).name()) << "): " << ex << std::endl;
throw;
}
}
// -----------------------------------------------------------------------------------------
} // endof namespace UniSetTypes
// -----------------------------------------------------------------------------------------
#endif // UHelpers_H_
......@@ -203,7 +203,6 @@ class UniSetObject:
return MaxCountRemoveOfMessage;
}
// функция определения приоритетного сообщения для обработки
struct PriorVMsgCompare:
public std::binary_function<UniSetTypes::VoidMessage, UniSetTypes::VoidMessage, bool>
......@@ -243,6 +242,19 @@ class UniSetObject:
void setThreadPriority( int p );
// ------- Статистика -------
/*! максимальное количество которое было в очереди сообщений */
inline size_t getMaxQueueMessages()
{
return stMaxQueueMessages;
}
/*! сколько раз очередь переполнялась */
inline size_t getCountOfQueueFull()
{
return stCountOfQueueFull;
}
private:
friend class UniSetManager;
......@@ -294,8 +306,8 @@ class UniSetObject:
size_t MaxCountRemoveOfMessage;
// статистическая информация
size_t stMaxQueueMessages; /*<! Максимальное число сообщений хранившихся в очереди */
size_t stCountOfQueueFull; /*!< количество переполнений очереди сообщений */
size_t stMaxQueueMessages = { 0 }; /*!< Максимальное число сообщений хранившихся в очереди */
size_t stCountOfQueueFull = { 0 }; /*!< количество переполнений очереди сообщений */
std::atomic_bool a_working;
std::mutex m_working;
......
......@@ -214,6 +214,10 @@ extensions/tests/tests_with_sm.xml
extensions/tests/u.xml
extensions/tests/sm_perf_test.cc
extensions/tests/develop.cc
extensions/tests/MQPerfTest/Makefile.am
extensions/tests/MQPerfTest/TestProc.h
extensions/tests/MQPerfTest/TestProc.cc
extensions/tests/MQPerfTest/mq-test.cc
extensions/UNetUDP/tests/Makefile.am
extensions/UNetUDP/tests/test_unetudp.cc
extensions/UNetUDP/tests/tests_individual_process.cc
......@@ -318,6 +322,7 @@ include/UInterface.h
include/UniSetActivator.h
include/UniSetManager.h
include/UniSetObject.h
include/UMessageQueue.h
include/UniSetTypes.h
include/UniXML.h
include/UTCPCore.h
......@@ -326,6 +331,7 @@ include/UTCPSocket.h
include/USocket.h
include/UDPCore.h
include/WDTInterface.h
include/UHelpers.h
lib/Makefile.am
python/examples/test.xml
python/lib/pyUniSet/Makefile.am
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment