Commit 40a0da8d authored by Pavel Vainerman's avatar Pavel Vainerman

(SharedMemory): первый вариант механизма восстановления данных из резервной SM.

parent 0ea9f7dd
...@@ -62,6 +62,9 @@ ...@@ -62,6 +62,9 @@
<item filter="a1" fuse_id="AlarmFuse1_S" fuse_invert="1" id="1" size="30"/> <item filter="a1" fuse_id="AlarmFuse1_S" fuse_invert="1" id="1" size="30"/>
<item filter="a2" fuse_id="AlarmFuse2_AS" fuse_value="2" id="2" size="30"/> <item filter="a2" fuse_id="AlarmFuse2_AS" fuse_value="2" id="2" size="30"/>
</History> </History>
<ReservList>
<item node="LocalhostNode" name="ReservSharedMemory"/>
</ReservList>
</SharedMemory> </SharedMemory>
<UniExchange name="UniExchange"> <UniExchange name="UniExchange">
<item name="UniExchange2" node="Node2"/> <item name="UniExchange2" node="Node2"/>
...@@ -261,6 +264,7 @@ ...@@ -261,6 +264,7 @@
<item id="5003" name="SharedMemory"/> <item id="5003" name="SharedMemory"/>
<item id="5001" name="UniExchange"/> <item id="5001" name="UniExchange"/>
<item id="5002" name="UniExchange2"/> <item id="5002" name="UniExchange2"/>
<item id="5004" name="ReservSharedMemory"/>
</controllers> </controllers>
<!-- ******************* Идентификаторы сервисов ***************** --> <!-- ******************* Идентификаторы сервисов ***************** -->
<services name="Services"> <services name="Services">
......
...@@ -35,11 +35,11 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std: ...@@ -35,11 +35,11 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std:
IONotifyController_LT(id), IONotifyController_LT(id),
heartbeatCheckTime(5000), heartbeatCheckTime(5000),
histSaveTime(0), histSaveTime(0),
wdt(0),
activated(false), activated(false),
workready(false), workready(false),
dblogging(false), dblogging(false),
msecPulsar(0) msecPulsar(0),
confnode(0)
{ {
mutex_start.setName(myname + "_mutex_start"); mutex_start.setName(myname + "_mutex_start");
...@@ -49,14 +49,14 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std: ...@@ -49,14 +49,14 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std:
if( cname.empty() ) if( cname.empty() )
cname = ORepHelpers::getShortName( conf->oind->getMapName(id)); cname = ORepHelpers::getShortName( conf->oind->getMapName(id));
xmlNode* cnode = conf->getNode(cname); confnode = conf->getNode(cname);
if( cnode == NULL ) if( confnode == NULL )
throw SystemError("Not found conf-node for " + cname ); throw SystemError("Not found conf-node for " + cname );
UniXML::iterator it(cnode); UniXML::iterator it(confnode);
// ---------------------- // ----------------------
buildHistoryList(cnode); buildHistoryList(confnode);
signal_change_value().connect(sigc::mem_fun(*this, &SharedMemory::updateHistory)); signal_change_value().connect(sigc::mem_fun(*this, &SharedMemory::updateHistory));
for( auto i=hist.begin(); i!=hist.end(); ++i ) for( auto i=hist.begin(); i!=hist.end(); ++i )
histmap[i->fuse_id].push_back(i); histmap[i->fuse_id].push_back(i);
...@@ -90,14 +90,14 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std: ...@@ -90,14 +90,14 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std:
string wdt_dev = conf->getArgParam("--wdt-device"); string wdt_dev = conf->getArgParam("--wdt-device");
if( !wdt_dev.empty() ) if( !wdt_dev.empty() )
wdt = new WDTInterface(wdt_dev); wdt = make_shared<WDTInterface>(wdt_dev);
else else
dwarn << myname << "(init): watchdog timer NOT USED (--wdt-device NULL)" << endl; dwarn << myname << "(init): watchdog timer NOT USED (--wdt-device NULL)" << endl;
dblogging = conf->getArgInt("--db-logging"); dblogging = conf->getArgInt("--db-logging");
e_filter = conf->getArgParam("--e-filter"); e_filter = conf->getArgParam("--e-filter");
buildEventList(cnode); buildEventList(confnode);
evntPause = conf->getArgPInt("--e-startup-pause", 5000); evntPause = conf->getArgPInt("--e-startup-pause", 5000);
...@@ -128,8 +128,6 @@ SharedMemory::~SharedMemory() ...@@ -128,8 +128,6 @@ SharedMemory::~SharedMemory()
delete restorer; delete restorer;
restorer = NULL; restorer = NULL;
} }
delete wdt;
} }
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
...@@ -252,6 +250,9 @@ bool SharedMemory::activateObject() ...@@ -252,6 +250,9 @@ bool SharedMemory::activateObject()
hit.ioit = myioEnd(); hit.ioit = myioEnd();
} }
// здесь или в startUp?
initFromReserv();
activated = true; activated = true;
} }
...@@ -747,4 +748,125 @@ std::ostream& operator<<( std::ostream& os, const SharedMemory::HistoryInfo& h ) ...@@ -747,4 +748,125 @@ std::ostream& operator<<( std::ostream& os, const SharedMemory::HistoryInfo& h )
return os; return os;
} }
// ------------------------------------------------------------------------------------------ // ----------------------------------------------------------------------------
void SharedMemory::initFromReserv()
{
UniXML::iterator it(confnode);
if( !it.find("ReservList") )
{
dinfo << myname << "(initFromReserv): <ReservList> not found... ignore.. " << endl;
return;
}
if( !it.goChildren() )
{
dwarn << myname << "(initFromReserv): <ReservList> EMPTY?... ignore.. " << endl;
return;
}
auto conf = uniset_conf();
for( ; it.getCurrent(); it++ )
{
ObjectId sm_id = DefaultObjectId;
ObjectId sm_node = DefaultObjectId;
std::string smName(it.getProp("name"));
if( !smName.empty() )
sm_id = conf->getControllerID(smName);
else
sm_id = getId();
if( sm_id == DefaultObjectId )
{
ostringstream err;
err << myname << "(initFromReserv): Not found ID for '" << smName << "'";
dcrit << err.str() << endl;
// throw SystemError(err.str());
raise(SIGTERM);
}
std::string smNode(it.getProp("node"));
if( !smNode.empty() )
sm_node = conf->getNodeID(smNode);
else
sm_node = conf->getLocalNode();
if( sm_node == DefaultObjectId )
{
ostringstream err;
err << myname << "(initFromReserv): Not found NodeID for '" << smNode << "'";
dcrit << err.str() << endl;
// throw SystemError(err.str());
raise(SIGTERM);
}
if( sm_id == getId() && sm_node == conf->getLocalNode() )
{
dcrit << myname << "(initFromReserv): Initialization of himself?! ignore.." << endl;
continue;
}
if( initFromSM(sm_id,sm_node) )
{
dinfo << myname << "(initFromReserv): init from sm_id='" << smName << "' sm_node='" << smNode << "' [OK]" << endl;
return;
}
dinfo << myname << "(initFromReserv): init from sm_id='" << smName << "' sm_node='" << smNode << "' [FAILED]" << endl;
}
dwarn << myname << "(initFromReserv): FAILED INIT FROM <ReservList>" << endl;
}
// ----------------------------------------------------------------------------
bool SharedMemory::initFromSM( UniSetTypes::ObjectId sm_id, UniSetTypes::ObjectId sm_node )
{
dinfo << myname << "(initFromSM): init from sm_id='" << sm_id << "' sm_node='" << sm_node << "'" << endl;
// SENSORS MAP
try
{
IOController_i::SensorInfoSeq_var amap = ui->getSensorsMap(sm_id,sm_node);
int size = amap->length();
for( int i=0; i<size; i++ )
{
IOController_i::SensorIOInfo& ii(amap[i]);
try
{
#if 0
// Вариант через setValue...
setValue(ii.si.id,ii.value,getId());
#else
// Вариант с прямым обновлением внутреннего состояния
IOStateList::iterator io = myiofind(ii.si.id);
if( io == myioEnd() )
{
dcrit << myname << "(initFromSM): not found sensor id=" << ii.si.id << "'" << endl;
continue;
}
io->second->init(ii);
#endif
}
catch( const Exception& ex )
{
dcrit << myname << "(initFromSM): " << ex << endl;
}
catch( const IOController_i::NameNotFound& ex )
{
dcrit << myname << "(initFromSM): not found sensor id=" << ii.si.id << "'" << endl;
}
}
return true;
}
catch( const UniSetTypes::Exception& ex )
{
dwarn << myname << "(initFromSM): " << ex << endl;
}
return false;
}
// ----------------------------------------------------------------------------
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
- \ref sec_SM_History - \ref sec_SM_History
- \ref sec_SM_Pulsar - \ref sec_SM_Pulsar
- \ref sec_SM_DBLog - \ref sec_SM_DBLog
- \ref sec_SM_ReservSM
\section sec_SM_Conf Определение списка регистрируемых датчиков \section sec_SM_Conf Определение списка регистрируемых датчиков
SM позволяет определять список датчиков, которые он будет предоставлять SM позволяет определять список датчиков, которые он будет предоставлять
...@@ -253,6 +254,24 @@ ...@@ -253,6 +254,24 @@
(реализованное в базовом классе IONotifyController). (реализованное в базовом классе IONotifyController).
Параметр командной строки \b --db-logging 1 позволяет включить этот механизм Параметр командной строки \b --db-logging 1 позволяет включить этот механизм
(в свою очередь работа с БД требует отдельной настройки). (в свою очередь работа с БД требует отдельной настройки).
\section sec_SM_ReservSM Восстановление данных из резервных SM
Для повышения надёжности работы в SharedMemory предусмотрен механизм восстановления текущий состояний
из списка резервных SM. После того, как SM запускается и активизируется, но до того, как она
выдаст exit()=true и с ней можно будет работать, происходит попытка получить значения всех датчиков
от резервных SM. Список резервных SM задаётся в секции <ReservList>...</ReservList>.
При этом попытки получить значения идёт в порядке указанном в списке и прекращаются, при первом успешном
доступе.
\code
<SharedMemory ...>
...
<ReservList>
<item name="SharedMemory" node="reservnode"/>
<item name="SharedMemory" node="reservnode2"/>
...
</ReservList>
</SharedMemory>
\endcode
*/ */
class SharedMemory: class SharedMemory:
public IONotifyController_LT public IONotifyController_LT
...@@ -357,12 +376,12 @@ class SharedMemory: ...@@ -357,12 +376,12 @@ class SharedMemory:
virtual void timerInfo( const UniSetTypes::TimerMessage *tm ) override; virtual void timerInfo( const UniSetTypes::TimerMessage *tm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd ); virtual void askSensors( UniversalIO::UIOCommand cmd );
void sendEvent( UniSetTypes::SystemMessage& sm ); void sendEvent( UniSetTypes::SystemMessage& sm );
void initFromReserv();
bool initFromSM( UniSetTypes::ObjectId sm_id, UniSetTypes::ObjectId sm_node );
// действия при завершении работы // действия при завершении работы
virtual void sigterm( int signo ) override; virtual void sigterm( int signo ) override;
virtual bool activateObject() override; virtual bool activateObject() override;
// virtual void logging(UniSetTypes::SensorMessage& sm){}
// virtual void dumpToDB(){}
bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec ); bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec );
void buildEventList( xmlNode* cnode ); void buildEventList( xmlNode* cnode );
...@@ -410,7 +429,7 @@ class SharedMemory: ...@@ -410,7 +429,7 @@ class SharedMemory:
typedef std::list<HeartBeatInfo> HeartBeatList; typedef std::list<HeartBeatInfo> HeartBeatList;
HeartBeatList hlist; // список датчиков "сердцебиения" HeartBeatList hlist; // список датчиков "сердцебиения"
WDTInterface* wdt; std::shared_ptr<WDTInterface> wdt;
std::atomic_bool activated; std::atomic_bool activated;
std::atomic_bool workready; std::atomic_bool workready;
...@@ -439,6 +458,8 @@ class SharedMemory: ...@@ -439,6 +458,8 @@ class SharedMemory:
UniSetTypes::ObjectId sidPulsar; UniSetTypes::ObjectId sidPulsar;
int msecPulsar; int msecPulsar;
xmlNode* confnode;
private: private:
HistorySlot m_historySignal; HistorySlot m_historySignal;
}; };
......
...@@ -58,6 +58,9 @@ ...@@ -58,6 +58,9 @@
<item filter="a1" fuse_id="AlarmFuse1_S" fuse_invert="1" id="1" size="30"/> <item filter="a1" fuse_id="AlarmFuse1_S" fuse_invert="1" id="1" size="30"/>
<item filter="a2" fuse_id="AlarmFuse2_AS" fuse_value="2" id="2" size="30"/> <item filter="a2" fuse_id="AlarmFuse2_AS" fuse_value="2" id="2" size="30"/>
</History> </History>
<ReservList>
<item node="localhost" name="ReservSharedMemory"/>
</ReservList>
</SharedMemory> </SharedMemory>
<UniExchange name="UniExchange"> <UniExchange name="UniExchange">
<item name="UniExchange2" node="Node2"/> <item name="UniExchange2" node="Node2"/>
...@@ -279,6 +282,7 @@ ...@@ -279,6 +282,7 @@
<item id="5003" name="SharedMemory"/> <item id="5003" name="SharedMemory"/>
<item id="5001" name="UniExchange"/> <item id="5001" name="UniExchange"/>
<item id="5002" name="UniExchange2"/> <item id="5002" name="UniExchange2"/>
<item id="5004" name="ReservSharedMemory"/>
</controllers> </controllers>
<!-- ******************* Идентификаторы сервисов ***************** --> <!-- ******************* Идентификаторы сервисов ***************** -->
<services name="Services"> <services name="Services">
......
...@@ -303,6 +303,8 @@ class IOController: ...@@ -303,6 +303,8 @@ class IOController:
// функция обработки информации об изменении состояния датчика, от которого зависит данный // функция обработки информации об изменении состояния датчика, от которого зависит данный
void checkDepend( std::shared_ptr<USensorInfo>& it, IOController* ); void checkDepend( std::shared_ptr<USensorInfo>& it, IOController* );
void init( const IOController_i::SensorIOInfo& s );
}; };
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
......
...@@ -156,6 +156,11 @@ class UInterface ...@@ -156,6 +156,11 @@ class UInterface
IOController_i::ShortMapSeq* getSensors( const UniSetTypes::ObjectId id, IOController_i::ShortMapSeq* getSensors( const UniSetTypes::ObjectId id,
const UniSetTypes::ObjectId node = UniSetTypes::uniset_conf()->getLocalNode() ); const UniSetTypes::ObjectId node = UniSetTypes::uniset_conf()->getLocalNode() );
IOController_i::SensorInfoSeq* getSensorsMap( const UniSetTypes::ObjectId id,
const UniSetTypes::ObjectId node = UniSetTypes::uniset_conf()->getLocalNode() );
IONotifyController_i::ThresholdsListSeq* getThresholdsList( const UniSetTypes::ObjectId id,
const UniSetTypes::ObjectId node = UniSetTypes::uniset_conf()->getLocalNode() );
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Работа с репозиторием // Работа с репозиторием
......
...@@ -1910,6 +1910,152 @@ IOController_i::ShortMapSeq* UInterface::getSensors( const UniSetTypes::ObjectId ...@@ -1910,6 +1910,152 @@ IOController_i::ShortMapSeq* UInterface::getSensors( const UniSetTypes::ObjectId
throw UniSetTypes::TimeOut(set_err("UI(getSensors): Timeout",id,node)); throw UniSetTypes::TimeOut(set_err("UI(getSensors): Timeout",id,node));
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
IOController_i::SensorInfoSeq* UInterface::getSensorsMap( const UniSetTypes::ObjectId id, UniSetTypes::ObjectId node )
{
if ( id == DefaultObjectId )
throw ORepFailed("UI(getSensorsMap): error node=UniSetTypes::DefaultObjectId");
if ( node == DefaultObjectId )
throw ORepFailed("UI(getSensorsMap): error node=UniSetTypes::DefaultObjectId");
try
{
CORBA::Object_var oref;
try
{
oref = rcache.resolve(id,node);
}
catch( const NameNotFound& ){}
for( unsigned int i=0; i<uconf->getRepeatCount(); i++)
{
try
{
if( CORBA::is_nil(oref) )
oref = resolve(id,node);
IOController_i_var iom = IOController_i::_narrow(oref);
return iom->getSensorsMap();
}
catch( const CORBA::TRANSIENT& ){}
catch( const CORBA::OBJECT_NOT_EXIST& ){}
catch( const CORBA::SystemException& ex ){}
msleep(uconf->getRepeatTimeout());
oref = CORBA::Object::_nil();
}
}
catch( const UniSetTypes::TimeOut& ){}
catch(const IOController_i::NameNotFound& ex)
{
rcache.erase(id,node);
throw UniSetTypes::NameNotFound("UI(getSensorsMap): "+string(ex.err));
}
catch(const IOController_i::IOBadParam& ex)
{
rcache.erase(id, node);
throw UniSetTypes::IOBadParam("UI(getSensorsMap): "+string(ex.err));
}
catch(const ORepFailed& )
{
rcache.erase(id,node);
// не смогли получить ссылку на объект
throw UniSetTypes::IOBadParam(set_err("UI(getSensorsMap): resolve failed ",id,node));
}
catch(const CORBA::NO_IMPLEMENT& )
{
rcache.erase(id,node);
throw UniSetTypes::IOBadParam(set_err("UI(getSensorsMap): method no implement",id,node));
}
catch( const CORBA::OBJECT_NOT_EXIST& )
{
rcache.erase(id,node);
throw UniSetTypes::IOBadParam(set_err("UI(getSensorsMap): object not exist",id,node));
}
catch( const CORBA::COMM_FAILURE& ex )
{
// ошибка системы коммуникации
}
catch( const CORBA::SystemException& ex )
{
// ошибка системы коммуникации
}
rcache.erase(id,node);
throw UniSetTypes::TimeOut(set_err("UI(getSensorsMap): Timeout",id,node));
}
// -----------------------------------------------------------------------------
IONotifyController_i::ThresholdsListSeq* UInterface::getThresholdsList( const UniSetTypes::ObjectId id, UniSetTypes::ObjectId node )
{
if ( id == DefaultObjectId )
throw ORepFailed("UI(getThresholdsList): error node=UniSetTypes::DefaultObjectId");
if ( node == DefaultObjectId )
throw ORepFailed("UI(getThresholdsList): error node=UniSetTypes::DefaultObjectId");
try
{
CORBA::Object_var oref;
try
{
oref = rcache.resolve(id,node);
}
catch( const NameNotFound& ){}
for( unsigned int i=0; i<uconf->getRepeatCount(); i++)
{
try
{
if( CORBA::is_nil(oref) )
oref = resolve(id,node);
IONotifyController_i_var iom = IONotifyController_i::_narrow(oref);
return iom->getThresholdsList();
}
catch( const CORBA::TRANSIENT& ){}
catch( const CORBA::OBJECT_NOT_EXIST& ){}
catch( const CORBA::SystemException& ex ){}
msleep(uconf->getRepeatTimeout());
oref = CORBA::Object::_nil();
}
}
catch( const UniSetTypes::TimeOut& ){}
catch(const IOController_i::NameNotFound& ex)
{
rcache.erase(id,node);
throw UniSetTypes::NameNotFound("UI(getThresholdsList): "+string(ex.err));
}
catch(const IOController_i::IOBadParam& ex)
{
rcache.erase(id, node);
throw UniSetTypes::IOBadParam("UI(getThresholdsList): "+string(ex.err));
}
catch(const ORepFailed& )
{
rcache.erase(id,node);
// не смогли получить ссылку на объект
throw UniSetTypes::IOBadParam(set_err("UI(getThresholdsList): resolve failed ",id,node));
}
catch(const CORBA::NO_IMPLEMENT& )
{
rcache.erase(id,node);
throw UniSetTypes::IOBadParam(set_err("UI(getThresholdsList): method no implement",id,node));
}
catch( const CORBA::OBJECT_NOT_EXIST& )
{
rcache.erase(id,node);
throw UniSetTypes::IOBadParam(set_err("UI(getThresholdsList): object not exist",id,node));
}
catch( const CORBA::COMM_FAILURE& ex )
{
// ошибка системы коммуникации
}
catch( const CORBA::SystemException& ex )
{
// ошибка системы коммуникации
}
rcache.erase(id,node);
throw UniSetTypes::TimeOut(set_err("UI(getThresholdsList): Timeout",id,node));
}
// -----------------------------------------------------------------------------
bool UInterface::waitReady( const ObjectId id, int msec, int pmsec, const ObjectId node ) bool UInterface::waitReady( const ObjectId id, int msec, int pmsec, const ObjectId node )
{ {
if( msec < 0 ) if( msec < 0 )
......
...@@ -617,6 +617,11 @@ const IOController::USensorInfo& ...@@ -617,6 +617,11 @@ const IOController::USensorInfo&
return *this; return *this;
} }
void IOController::USensorInfo::init( const IOController_i::SensorIOInfo& s )
{
IOController::USensorInfo r(s);
(*this) = std::move(r);
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
bool IOController::checkIOFilters( std::shared_ptr<USensorInfo>& ai, CORBA::Long& newvalue, bool IOController::checkIOFilters( std::shared_ptr<USensorInfo>& ai, CORBA::Long& newvalue,
UniSetTypes::ObjectId sup_id ) UniSetTypes::ObjectId sup_id )
......
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