Commit 5af07e59 authored by Pavel Vainerman's avatar Pavel Vainerman

(RRDServer): исправлена ошибка последовательности записи данных в rrd

parent 0a10cf47
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
Name: libuniset2 Name: libuniset2
Version: 2.2 Version: 2.2
Release: alt20 Release: alt21
Summary: UniSet - library for building distributed industrial control systems Summary: UniSet - library for building distributed industrial control systems
...@@ -451,6 +451,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -451,6 +451,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# .. # ..
%changelog %changelog
* Sat Feb 06 2016 Pavel Vainerman <pv@altlinux.ru> 2.2-alt21
- RRDServer: fixed bug in write sequence to rrd base
* Sat Feb 06 2016 Pavel Vainerman <pv@altlinux.ru> 2.2-alt20 * Sat Feb 06 2016 Pavel Vainerman <pv@altlinux.ru> 2.2-alt20
- RRDServer: fixed bug for long name processing.. - RRDServer: fixed bug for long name processing..
......
...@@ -135,10 +135,10 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID ) ...@@ -135,10 +135,10 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID )
throw SystemError(err.str()); throw SystemError(err.str());
} }
DSMap dsmap; DSList dslist;
// список параметров входящих в RRD // список параметров входящих в RRD
std::list<std::string> dslist; std::list<std::string> rrdparamist;
for(; it1.getCurrent(); it1.goNext() ) for(; it1.getCurrent(); it1.goNext() )
{ {
...@@ -171,7 +171,7 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID ) ...@@ -171,7 +171,7 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID )
ostringstream nm; ostringstream nm;
nm << "DS:" << dsname << ":" << a; nm << "DS:" << dsname << ":" << a;
dslist.push_back(nm.str()); rrdparamist.push_back(nm.str());
ObjectId sid = conf->getSensorID( it1.getProp("name") ); ObjectId sid = conf->getSensorID( it1.getProp("name") );
...@@ -183,11 +183,11 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID ) ...@@ -183,11 +183,11 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID )
throw SystemError(err.str()); throw SystemError(err.str());
} }
DSInfo ds(dsname, it1.getIntProp("default")); auto ds = make_shared<DSInfo>(sid, dsname, it1.getIntProp("default"));
dsmap.emplace(sid, ds); dslist.push_back(ds);
} }
if( dslist.empty() ) if( rrdparamist.empty() )
{ {
ostringstream err; ostringstream err;
err << myname << "(init): Not found RRD items..."; err << myname << "(init): Not found RRD items...";
...@@ -195,12 +195,12 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID ) ...@@ -195,12 +195,12 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID )
throw SystemError(err.str()); throw SystemError(err.str());
} }
char argc = dslist.size() + rralist.size(); char argc = rrdparamist.size() + rralist.size();
char** argv = new char* [ argc ]; char** argv = new char* [ argc ];
int k = 0; int k = 0;
for( auto& i : dslist ) for( auto& i : rrdparamist )
argv[k++] = strdup(i.c_str()); argv[k++] = strdup(i.c_str());
for( auto& i : rralist ) for( auto& i : rralist )
...@@ -234,17 +234,8 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID ) ...@@ -234,17 +234,8 @@ void RRDServer::initRRD( xmlNode* cnode, int tmID )
delete[] argv; delete[] argv;
rrdlist.emplace_back(fname, tmID, rrdstep, dsmap); rrdlist.emplace_back(fname, tmID, rrdstep, dslist);
} }
/* catch( const Exception& ex )
{
mycrit << myname << "(init) " << ex << std::endl;
}
catch( ... )
{
mycrit << myname << "(init): catch ..." << std::endl;
}
*/
} }
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
void RRDServer::help_print( int argc, const char* const* argv ) void RRDServer::help_print( int argc, const char* const* argv )
...@@ -352,7 +343,7 @@ void RRDServer::sensorInfo( const UniSetTypes::SensorMessage* sm ) ...@@ -352,7 +343,7 @@ void RRDServer::sensorInfo( const UniSetTypes::SensorMessage* sm )
auto s = it.dsmap.find(sm->id); auto s = it.dsmap.find(sm->id);
if( s != it.dsmap.end() ) if( s != it.dsmap.end() )
s->second.value = sm->value; s->second->value = sm->value;
// продолжаем искать по другим rrd, т.к. датчик может входить в несколько.. // продолжаем искать по другим rrd, т.к. датчик может входить в несколько..
} }
...@@ -367,14 +358,17 @@ void RRDServer::timerInfo( const UniSetTypes::TimerMessage* tm ) ...@@ -367,14 +358,17 @@ void RRDServer::timerInfo( const UniSetTypes::TimerMessage* tm )
ostringstream v; ostringstream v;
v << time(0); v << time(0);
for( auto& s : it.dsmap ) // здесь идём по списку (а не dsmap)
v << ":" << s.second.value; // т.к. важна последовательность
for( const auto& s : it.dslist )
v << ":" << s->value;
myinfo << myname << "(update): '" << it.filename << "' " << v.str() << endl; myinfo << myname << "(update): '" << it.filename << "' " << v.str() << endl;
rrd_clear_error(); rrd_clear_error();
const char* argv = uni_strdup(v.str().c_str()); const std::string tmp(v.str()); // надежда на RVO оптимизацию
const char* argv = tmp.c_str();
if( rrd_update_r(it.filename.c_str(), NULL, 1, &argv) < 0 ) if( rrd_update_r(it.filename.c_str(), NULL, 1, &argv) < 0 )
{ {
...@@ -383,9 +377,16 @@ void RRDServer::timerInfo( const UniSetTypes::TimerMessage* tm ) ...@@ -383,9 +377,16 @@ void RRDServer::timerInfo( const UniSetTypes::TimerMessage* tm )
mycrit << err.str() << endl; mycrit << err.str() << endl;
} }
delete[] argv;
break; break;
} }
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
RRDServer::RRDInfo::RRDInfo(const string& fname, long tmID, long sec, const RRDServer::DSList& lst):
filename(fname), tid(tmID), sec(sec), dslist(lst)
{
// фомируем dsmap
for( auto&& i: dslist )
dsmap.emplace(i->sid,i);
}
// -----------------------------------------------------------------------------
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define _RRDServer_H_ #define _RRDServer_H_
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include <unordered_map> #include <unordered_map>
#include <list>
#include <memory> #include <memory>
#include "UObject_SK.h" #include "UObject_SK.h"
#include "SMInterface.h" #include "SMInterface.h"
...@@ -103,14 +104,21 @@ class RRDServer: ...@@ -103,14 +104,21 @@ class RRDServer:
struct DSInfo struct DSInfo
{ {
UniSetTypes::ObjectId sid;
std::string dsname; std::string dsname;
long value; long value;
DSInfo( const std::string& dsname, long defval ): DSInfo( UniSetTypes::ObjectId id, const std::string& dsname, long defval ):
dsname(dsname), value(defval) {} sid(id), dsname(dsname), value(defval) {}
}; };
typedef std::unordered_map<UniSetTypes::ObjectId, DSInfo> DSMap; // Т.к. RRD требует чтобы данные записывались именно в том порядке в котором они были добавлены
// при инициализации и при этом, нам нужен быстрый доступ в обработчике sensorInfo.
// То создаём list<> для последовательного прохода по элементам в нужном порядке
// и unordered_map<> для быстрого доступа к элементам в sensorInfo
// При этом используем shared_ptr чтобы элементы указывали на один и тот же DSInfo
typedef std::unordered_map<UniSetTypes::ObjectId, std::shared_ptr<DSInfo>> DSMap;
typedef std::list<std::shared_ptr<DSInfo>> DSList;
struct RRDInfo struct RRDInfo
{ {
...@@ -118,9 +126,9 @@ class RRDServer: ...@@ -118,9 +126,9 @@ class RRDServer:
long tid; long tid;
long sec; long sec;
DSMap dsmap; DSMap dsmap;
DSList dslist;
RRDInfo( const std::string& fname, long tmID, long sec, const DSMap& ds ): RRDInfo( const std::string& fname, long tmID, long sec, const DSList& lst );
filename(fname), tid(tmID), sec(sec), dsmap(ds) {}
}; };
typedef std::list<RRDInfo> RRDList; typedef std::list<RRDInfo> RRDList;
......
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