Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+249
@@ -0,0 +1,249 @@
|
||||
/**
|
||||
* The ServiceHandler class handles all service related classes and writes the services state to DDS.
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-02-15
|
||||
*/
|
||||
|
||||
#include "service_handler.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
|
||||
#include "service.h"
|
||||
#include "service_process.h"
|
||||
#include "dds_handler.h"
|
||||
#include "settings.h"
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
|
||||
ServiceManagement::ServiceHandler::ServiceHandler(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<LicenceDonator> &licenceDonator)
|
||||
: ServiceDonator()
|
||||
, Interface::Fts::RestartServiceRequestHandler(ddsHandler->fts())
|
||||
, m_heartBeatObserverTimer(new QTimer(this))
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_licenceDonator(licenceDonator)
|
||||
, m_logger(getLogger("ServiceHandler"))
|
||||
{
|
||||
connect(qApp, &QCoreApplication::aboutToQuit,
|
||||
this, &ServiceHandler::stopAllServices);
|
||||
}
|
||||
|
||||
ServiceManagement::ServiceHandler::~ServiceHandler()
|
||||
{
|
||||
qDeleteAll(m_services);
|
||||
m_services.clear();
|
||||
}
|
||||
|
||||
bool ServiceManagement::ServiceHandler::init()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Initializing ServiceHandler ...";
|
||||
|
||||
connect(m_heartBeatObserverTimer, &QTimer::timeout,
|
||||
this, &ServiceHandler::onHeartBeatObserverTimerTimeout);
|
||||
|
||||
|
||||
HEARTBEAT_OBSERVER_INTERVAL = Settings::observerIntervall();
|
||||
DEBUG_LOG(m_logger) << HEARTBEAT_OBSERVER_INTERVAL;
|
||||
m_heartBeatObserverTimer->start(HEARTBEAT_OBSERVER_INTERVAL);
|
||||
|
||||
DEBUG_LOG(m_logger) << "ServiceHandler successfully initialized.";
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServiceManagement::ServiceHandler::addService(ServiceManagement::Service *service)
|
||||
{
|
||||
service->setParent(this);
|
||||
service->setLicenceDonator(m_licenceDonator);
|
||||
|
||||
connect(service, &Service::newServiceInfo,
|
||||
this, &ServiceHandler::onNewServiceInfoFromProc);
|
||||
|
||||
m_services.append(service);
|
||||
}
|
||||
|
||||
ServiceManagement::ServiceProcess *ServiceManagement::ServiceHandler::getProcess(int serviceId,
|
||||
const GroupRequest &groupData)
|
||||
{
|
||||
Service *service = serviceFromId(serviceId);
|
||||
|
||||
if (service == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return service->toServiceProcess(groupData);
|
||||
}
|
||||
|
||||
void ServiceManagement::ServiceHandler::onRestartServiceRequest(const rti::core::SampleIdentity &cookie,
|
||||
const RestartServiceRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onRestartServiceRequest " << request;
|
||||
|
||||
ServiceProcess *proc = serviceProcessFromServiceProcId(request.id());
|
||||
|
||||
Core::FunctionReplyObject ret(request.id());
|
||||
if (proc == nullptr)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Got restart request for non existing service ID "
|
||||
<< request.id();
|
||||
ret.setStr(tr_lts("dds", "There is no ServiceProcess with id %1")).arg(request.id());
|
||||
m_ddsHandler->fts()->restartServiceReply(cookie, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "Restart request for service "
|
||||
<< proc->serviceName()
|
||||
<< ", domain "
|
||||
<< proc->domainId()
|
||||
<< ", exercisePartitionId "
|
||||
<< proc->exercisePartitionId()
|
||||
<< ", replayPartitionId "
|
||||
<< proc->replayPartitionId();
|
||||
|
||||
proc->restart();
|
||||
|
||||
m_ddsHandler->fts()->restartServiceReply(cookie, ret);
|
||||
}
|
||||
|
||||
void ServiceManagement::ServiceHandler::stopAllServices()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Stopping all Services ...";
|
||||
|
||||
// shutdown async
|
||||
for (Service *service : qAsConst(m_services))
|
||||
service->stopAllProcs();
|
||||
for (Service *service : qAsConst(m_services))
|
||||
service->waitForStopped();
|
||||
|
||||
INFO_LOG(m_logger) << "... all Services stopped :)";
|
||||
}
|
||||
|
||||
void ServiceManagement::ServiceHandler::onNewServiceInfoFromProc(const ServiceInformation &info)
|
||||
{
|
||||
TRACE_LOG(m_logger) << "Publishing new ServiceInformation: " << info;
|
||||
|
||||
m_ddsHandler->dts()->publish(info);
|
||||
|
||||
m_unknownPidsWarned.remove(info.pid());
|
||||
}
|
||||
|
||||
void ServiceManagement::ServiceHandler::onNewServiceInfoFromDds(const Core::CurrentRunningState &data, DataModification type)
|
||||
{
|
||||
if (type == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
TRACE_LOG(m_logger) << "Got new CurrentRunningState: " << data;
|
||||
|
||||
if (!data.pid())
|
||||
{
|
||||
INFO_LOG(m_logger) << "PID 0 is not allowed.";
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceProcess *proc = serviceProcessFromPid(data.pid());
|
||||
Core::CurrentRunningState retData = data;
|
||||
|
||||
if (proc == nullptr)
|
||||
{
|
||||
bool found = false;
|
||||
for (Service *currentService : qAsConst(m_services))
|
||||
{
|
||||
for (ServiceProcess *currentProc : qAsConst(currentService->allProcs()))
|
||||
{
|
||||
if (currentProc->remotePid() == data.pid())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Found my prog " << data.pid() << " to "<< currentProc->pid() << " " << currentProc->serviceName();
|
||||
proc = currentProc;
|
||||
retData.pid() = proc->processId();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (proc == nullptr)
|
||||
{
|
||||
if (!m_unknownPidsWarned.contains(data.pid()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Got CurrentRunningState for non existing process with PID "
|
||||
<< data.pid();
|
||||
m_unknownPidsWarned += data.pid();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
proc->setNewStateFromHeartbeat(retData);
|
||||
}
|
||||
|
||||
ServiceManagement::Service *ServiceManagement::ServiceHandler::serviceFromId(int id)
|
||||
{
|
||||
for (Service *service : qAsConst(m_services))
|
||||
{
|
||||
if (service->id() == id)
|
||||
return service;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ServiceManagement::ServiceProcess *ServiceManagement::ServiceHandler::serviceProcessFromPid(qint64 pid)
|
||||
{
|
||||
for (Service *service : qAsConst(m_services))
|
||||
{
|
||||
ServiceProcess *result = service->procFromPid(pid);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ServiceManagement::ServiceProcess *ServiceManagement::ServiceHandler::serviceProcessFromServiceProcId(int32_t id)
|
||||
{
|
||||
for (Service *service : qAsConst(m_services))
|
||||
{
|
||||
ServiceProcess *result = service->procFromServiceProcId(id);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ServiceManagement::ServiceHandler::onHeartBeatObserverTimerTimeout()
|
||||
{
|
||||
const qint64 tNow = QDateTime::currentMSecsSinceEpoch();
|
||||
const qint64 minHeartbeatAge = tNow - HEARTBEAT_OBSERVER_INTERVAL;
|
||||
const qint64 minHeartbeatAgeStartup = tNow - HEARTBEAT_OBSERVER_INTERVAL * 6;
|
||||
|
||||
for (Service *currentService : qAsConst(m_services))
|
||||
{
|
||||
for (ServiceProcess *currentProc : qAsConst(currentService->allProcs()))
|
||||
{
|
||||
// dev mode for this proc -> we're not repsonsible for
|
||||
if (currentProc->devMode())
|
||||
continue;
|
||||
// stopped on operator demand -> we're not responsible for
|
||||
if (currentProc->stoppedFromRequest())
|
||||
continue;
|
||||
// there is something terribly wrong -> ignore
|
||||
if (currentProc->failedStartingAttempts() > 3)
|
||||
continue;
|
||||
|
||||
const qint64 minAge = (currentProc->runningState() == Core::RunningState_def::Starting)
|
||||
? minHeartbeatAgeStartup
|
||||
: minHeartbeatAge;
|
||||
|
||||
if (currentProc->lastHeartbeatMSec() < minAge)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Heartbeat TIMEOUT for " << currentProc->debugInfo()
|
||||
<< " - Restarting ..."
|
||||
<< " min heartbeat age: " << QDateTime::fromMSecsSinceEpoch(minHeartbeatAge).toString(QStringLiteral("HH:mm:ss"));
|
||||
currentProc->addStartAttempt();
|
||||
currentProc->restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user