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

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

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