mirror of https://github.com/Icinga/icinga2.git
Fine-grained locks (WIP, Part 7).
This commit is contained in:
parent
997ca3a77a
commit
5e91f6c54d
|
@ -60,6 +60,7 @@ void CheckerComponent::Stop(void)
|
|||
void CheckerComponent::CheckThreadProc(void)
|
||||
{
|
||||
for (;;) {
|
||||
vector<Service::Ptr> services;
|
||||
Service::Ptr service;
|
||||
|
||||
{
|
||||
|
@ -142,6 +143,11 @@ void CheckerComponent::CheckThreadProc(void)
|
|||
m_PendingServices.insert(service);
|
||||
}
|
||||
|
||||
double rwait = service->GetNextCheck() - Utility::GetTime();
|
||||
|
||||
if (abs(rwait - wait) > 5)
|
||||
Logger::Write(LogWarning, "checker", "Check delayed: " + Convert::ToString(-rwait) + ",planned wait: " + Convert::ToString(-wait));
|
||||
|
||||
try {
|
||||
service->BeginExecuteCheck(boost::bind(&CheckerComponent::CheckCompletedHandler, this, service));
|
||||
} catch (const exception& ex) {
|
||||
|
|
|
@ -91,7 +91,7 @@ String CompatComponent::GetCommandPath(void) const
|
|||
void CompatComponent::Start(void)
|
||||
{
|
||||
m_StatusTimer = boost::make_shared<Timer>();
|
||||
m_StatusTimer->SetInterval(5);
|
||||
m_StatusTimer->SetInterval(30);
|
||||
m_StatusTimer->OnTimerExpired.connect(boost::bind(&CompatComponent::StatusTimerHandler, this));
|
||||
m_StatusTimer->Start();
|
||||
m_StatusTimer->Reschedule(0);
|
||||
|
@ -544,22 +544,19 @@ void CompatComponent::StatusTimerHandler(void)
|
|||
}
|
||||
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("HostGroup")) {
|
||||
set<Host::Ptr> members;
|
||||
HostGroup::Ptr hg = static_pointer_cast<HostGroup>(object);
|
||||
|
||||
{
|
||||
HostGroup::Ptr hg = static_pointer_cast<HostGroup>(object);
|
||||
ObjectLock olock(hg);
|
||||
|
||||
objectfp << "define hostgroup {" << "\n"
|
||||
<< "\t" << "hostgroup_name" << "\t" << hg->GetName() << "\n"
|
||||
<< "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
|
||||
<< "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
|
||||
|
||||
members = hg->GetMembers();
|
||||
}
|
||||
|
||||
objectfp << "\t" << "members" << "\t";
|
||||
DumpNameList(objectfp, members);
|
||||
DumpNameList(objectfp, HostGroup::GetMembers(hg));
|
||||
objectfp << "\n"
|
||||
<< "}" << "\n";
|
||||
}
|
||||
|
@ -572,24 +569,21 @@ void CompatComponent::StatusTimerHandler(void)
|
|||
}
|
||||
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("ServiceGroup")) {
|
||||
set<Service::Ptr> members;
|
||||
ServiceGroup::Ptr sg = static_pointer_cast<ServiceGroup>(object);
|
||||
|
||||
{
|
||||
ServiceGroup::Ptr sg = static_pointer_cast<ServiceGroup>(object);
|
||||
ObjectLock olock(sg);
|
||||
|
||||
objectfp << "define servicegroup {" << "\n"
|
||||
<< "\t" << "servicegroup_name" << "\t" << sg->GetName() << "\n"
|
||||
<< "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
|
||||
<< "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
|
||||
|
||||
members = sg->GetMembers();
|
||||
}
|
||||
|
||||
objectfp << "\t" << "members" << "\t";
|
||||
|
||||
vector<String> sglist;
|
||||
BOOST_FOREACH(const Service::Ptr& service, members) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
|
||||
Host::Ptr host;
|
||||
String host_name, short_name;
|
||||
|
||||
|
|
|
@ -759,7 +759,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
|
|||
|
||||
vector<String> hglist;
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
|
||||
BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
|
||||
hglist.push_back(host->GetName());
|
||||
}
|
||||
|
||||
|
@ -793,7 +793,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
|
|||
vector<String> sglist;
|
||||
vector<Service::Ptr>::iterator vt;
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
|
||||
sglist.push_back(service->GetHost()->GetName());
|
||||
sglist.push_back(service->GetShortName());
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ signals2::signal<void (double, const set<DynamicObject::WeakPtr>&)> DynamicObjec
|
|||
signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnFlushObject;
|
||||
|
||||
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
||||
: m_Events(false), m_ConfigTx(0)
|
||||
: m_EventSafe(false), m_ConfigTx(0)
|
||||
{
|
||||
RegisterAttribute("__name", Attribute_Config);
|
||||
RegisterAttribute("__type", Attribute_Config);
|
||||
|
@ -88,7 +88,7 @@ void DynamicObject::SendLocalUpdateEvents(void)
|
|||
}
|
||||
|
||||
/* Check if it's safe to send events. */
|
||||
if (GetEvents()) {
|
||||
if (GetEventSafe()) {
|
||||
map<String, Value, string_iless>::iterator it;
|
||||
for (it = attrs.begin(); it != attrs.end(); it++)
|
||||
OnAttributeChanged(it->first, it->second);
|
||||
|
@ -237,19 +237,14 @@ void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
|||
if (tt.first->second.Type & Attribute_Config)
|
||||
m_ConfigTx = tx;
|
||||
|
||||
DynamicObject::Ptr self;
|
||||
try {
|
||||
self = GetSelf();
|
||||
} catch (const boost::bad_weak_ptr& ex) {
|
||||
/* We're being called from the constructor. Ignore
|
||||
* the exception. The OnInitCompleted() function
|
||||
* will take care of adding this object to the list
|
||||
* of modified objects. */
|
||||
}
|
||||
if (GetEventSafe()) {
|
||||
/* We can't call GetSelf() in the constructor or destructor.
|
||||
* The OnConstructionCompleted() function will take care of adding this
|
||||
* object to the list of modified objects later on if we can't
|
||||
* do it here. */
|
||||
|
||||
if (self) {
|
||||
boost::mutex::scoped_lock lock(m_TransactionMutex);
|
||||
m_ModifiedObjects.insert(self);
|
||||
m_ModifiedObjects.insert(GetSelf());
|
||||
}
|
||||
|
||||
/* Use insert() rather than [] so we don't overwrite
|
||||
|
@ -570,8 +565,11 @@ void DynamicObject::NewTx(void)
|
|||
OnTransactionClosing(tx, objects);
|
||||
}
|
||||
|
||||
void DynamicObject::OnInitCompleted(void)
|
||||
void DynamicObject::OnConstructionCompleted(void)
|
||||
{
|
||||
/* It's now safe to send us attribute events. */
|
||||
SetEventSafe(true);
|
||||
|
||||
/* Add this new object to the list of modified objects.
|
||||
* We're doing this here because we can't construct
|
||||
* a while WeakPtr from within the object's constructor. */
|
||||
|
@ -579,6 +577,9 @@ void DynamicObject::OnInitCompleted(void)
|
|||
m_ModifiedObjects.insert(GetSelf());
|
||||
}
|
||||
|
||||
void DynamicObject::OnRegistrationCompleted(void)
|
||||
{ }
|
||||
|
||||
void DynamicObject::OnAttributeChanged(const String&, const Value&)
|
||||
{ }
|
||||
|
||||
|
@ -600,12 +601,12 @@ const DynamicObject::AttributeMap& DynamicObject::GetAttributes(void) const
|
|||
return m_Attributes;
|
||||
}
|
||||
|
||||
void DynamicObject::SetEvents(bool events)
|
||||
void DynamicObject::SetEventSafe(bool safe)
|
||||
{
|
||||
m_Events = events;
|
||||
m_EventSafe = safe;
|
||||
}
|
||||
|
||||
bool DynamicObject::GetEvents(void) const
|
||||
bool DynamicObject::GetEventSafe(void) const
|
||||
{
|
||||
return m_Events;
|
||||
return m_EventSafe;
|
||||
}
|
||||
|
|
|
@ -125,8 +125,8 @@ public:
|
|||
|
||||
const AttributeMap& GetAttributes(void) const;
|
||||
|
||||
void SetEvents(bool events);
|
||||
bool GetEvents(void) const;
|
||||
void SetEventSafe(bool initialized);
|
||||
bool GetEventSafe(void) const;
|
||||
|
||||
static DynamicObject::Ptr GetObject(const String& type, const String& name);
|
||||
|
||||
|
@ -137,7 +137,8 @@ public:
|
|||
static double GetCurrentTx(void);
|
||||
|
||||
protected:
|
||||
virtual void OnInitCompleted(void);
|
||||
virtual void OnConstructionCompleted(void);
|
||||
virtual void OnRegistrationCompleted(void);
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
|
@ -149,7 +150,7 @@ private:
|
|||
map<String, Value, string_iless> m_ModifiedAttributes;
|
||||
double m_ConfigTx;
|
||||
|
||||
bool m_Events;
|
||||
bool m_EventSafe;
|
||||
|
||||
static double m_CurrentTx;
|
||||
|
||||
|
|
|
@ -80,29 +80,33 @@ String DynamicType::GetName(void) const
|
|||
|
||||
void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
|
||||
{
|
||||
ObjectLock olock(object);
|
||||
object->SetEvents(true);
|
||||
String name;
|
||||
|
||||
ObjectMap::iterator it = m_ObjectMap.find(object->GetName());
|
||||
{
|
||||
ObjectLock olock(object);
|
||||
name = object->GetName();
|
||||
}
|
||||
|
||||
ObjectMap::iterator it = m_ObjectMap.find(name);
|
||||
|
||||
if (it != m_ObjectMap.end()) {
|
||||
if (it->second == object)
|
||||
return;
|
||||
|
||||
BOOST_THROW_EXCEPTION(runtime_error("RegisterObject() found existing object with the same name: " + object->GetName()));
|
||||
BOOST_THROW_EXCEPTION(runtime_error("RegisterObject() found existing object with the same name: " + name));
|
||||
}
|
||||
|
||||
m_ObjectMap[object->GetName()] = object;
|
||||
m_ObjectMap[name] = object;
|
||||
m_ObjectSet.insert(object);
|
||||
|
||||
/* notify the object that it's been fully initialized */
|
||||
object->OnInitCompleted();
|
||||
/* notify the object that it's been registered */
|
||||
object->OnRegistrationCompleted();
|
||||
}
|
||||
|
||||
void DynamicType::UnregisterObject(const DynamicObject::Ptr& object)
|
||||
{
|
||||
ObjectLock olock(object);
|
||||
object->SetEvents(false);
|
||||
object->SetEventSafe(false);
|
||||
|
||||
m_ObjectMap.erase(object->GetName());
|
||||
m_ObjectSet.erase(object);
|
||||
|
@ -138,16 +142,21 @@ void DynamicType::RegisterType(const DynamicType::Ptr& type)
|
|||
DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUpdate) const
|
||||
{
|
||||
DynamicObject::Ptr object = m_ObjectFactory(serializedUpdate);
|
||||
ObjectLock olock(object);
|
||||
|
||||
/* register attributes */
|
||||
String name;
|
||||
DynamicAttributeType type;
|
||||
BOOST_FOREACH(tuples::tie(name, type), m_Attributes)
|
||||
object->RegisterAttribute(name, type);
|
||||
{
|
||||
ObjectLock olock(object);
|
||||
|
||||
/* apply the object's non-config attributes */
|
||||
object->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
||||
/* register attributes */
|
||||
String name;
|
||||
DynamicAttributeType type;
|
||||
BOOST_FOREACH(tuples::tie(name, type), m_Attributes)
|
||||
object->RegisterAttribute(name, type);
|
||||
|
||||
/* apply the object's non-config attributes */
|
||||
object->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
||||
}
|
||||
|
||||
object->OnConstructionCompleted();
|
||||
|
||||
return object;
|
||||
}
|
||||
|
|
|
@ -25,15 +25,13 @@ using namespace icinga;
|
|||
* @threadsafety Always.
|
||||
*/
|
||||
EventQueue::EventQueue(void)
|
||||
: m_Stopped(false)
|
||||
: m_Stopped(false), m_LastReport(0)
|
||||
{
|
||||
int thread_count = thread::hardware_concurrency();
|
||||
|
||||
if (thread_count < 4)
|
||||
thread_count = 4;
|
||||
|
||||
thread_count *= 4;
|
||||
|
||||
for (int i = 0; i < thread_count; i++)
|
||||
m_Threads.create_thread(boost::bind(&EventQueue::QueueThreadProc, this));
|
||||
}
|
||||
|
@ -116,4 +114,11 @@ void EventQueue::Post(const EventQueue::Callback& callback)
|
|||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_Events.push_back(callback);
|
||||
m_CV.notify_one();
|
||||
|
||||
int pending = m_Events.size();
|
||||
double now = Utility::GetTime();
|
||||
if (pending > 1000 && now - m_LastReport > 5) {
|
||||
Logger::Write(LogWarning, "base", "More than 1000 pending events: " + Convert::ToString(pending));
|
||||
m_LastReport = now;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ private:
|
|||
boost::mutex m_Mutex;
|
||||
condition_variable m_CV;
|
||||
|
||||
double m_LastReport;
|
||||
bool m_Stopped;
|
||||
vector<Callback> m_Events;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ using namespace icinga;
|
|||
boost::once_flag Process::m_ThreadOnce;
|
||||
boost::mutex Process::m_Mutex;
|
||||
deque<Process::Ptr> Process::m_Tasks;
|
||||
double Process::m_LastReport = 0;
|
||||
|
||||
Process::Process(const vector<String>& arguments, const Dictionary::Ptr& extraEnvironment)
|
||||
: AsyncTask<Process, ProcessResult>(), m_Arguments(arguments), m_ExtraEnvironment(extraEnvironment)
|
||||
|
@ -65,9 +66,18 @@ vector<String> Process::SplitCommand(const Value& command)
|
|||
|
||||
void Process::Run(void)
|
||||
{
|
||||
int count;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_Tasks.push_back(GetSelf());
|
||||
count = m_Tasks.size();
|
||||
}
|
||||
|
||||
if (count > 50 && Utility::GetTime() - m_LastReport > 5) {
|
||||
Logger::Write(LogInformation, "base", "More than 50 pending Process tasks: " +
|
||||
Convert::ToString(count));
|
||||
m_LastReport = Utility::GetTime();
|
||||
}
|
||||
|
||||
NotifyWorker();
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
typedef shared_ptr<Process> Ptr;
|
||||
typedef weak_ptr<Process> WeakPtr;
|
||||
|
||||
static const deque<Process::Ptr>::size_type MaxTasksPerThread = 512;
|
||||
static const deque<Process::Ptr>::size_type MaxTasksPerThread = 128;
|
||||
|
||||
Process(const vector<String>& arguments, const Dictionary::Ptr& extraEnvironment = Dictionary::Ptr());
|
||||
|
||||
|
@ -69,6 +69,7 @@ private:
|
|||
virtual void Run(void);
|
||||
|
||||
static boost::mutex m_Mutex;
|
||||
static double m_LastReport;
|
||||
static deque<Process::Ptr> m_Tasks;
|
||||
#ifndef _WIN32
|
||||
static int m_TaskFd;
|
||||
|
|
|
@ -32,9 +32,9 @@ Script::Script(const Dictionary::Ptr& properties)
|
|||
: DynamicObject(properties)
|
||||
{ }
|
||||
|
||||
void Script::OnInitCompleted(void)
|
||||
void Script::OnRegistrationCompleted(void)
|
||||
{
|
||||
DynamicObject::OnInitCompleted();
|
||||
DynamicObject::OnRegistrationCompleted();
|
||||
|
||||
SpawnInterpreter();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
String GetCode(void) const;
|
||||
|
||||
protected:
|
||||
virtual void OnInitCompleted(void);
|
||||
virtual void OnRegistrationCompleted(void);
|
||||
virtual void OnAttributeUpdate(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
|
|
|
@ -79,7 +79,10 @@ void StreamLogger::ProcessLogEntry(ostream& stream, bool tty, const LogEntry& en
|
|||
char timestamp[100];
|
||||
|
||||
time_t ts = entry.Timestamp;
|
||||
tm tmnow = *localtime(&ts);
|
||||
tm tmnow;
|
||||
|
||||
if (localtime_r(&ts, &tmnow) == NULL)
|
||||
BOOST_THROW_EXCEPTION(PosixException("localtime_r() failed.", errno));
|
||||
|
||||
strftime(timestamp, sizeof(timestamp), "%Y/%m/%d %H:%M:%S %z", &tmnow);
|
||||
|
||||
|
@ -98,7 +101,7 @@ void StreamLogger::ProcessLogEntry(ostream& stream, bool tty, const LogEntry& en
|
|||
}
|
||||
}
|
||||
|
||||
stream << "[" << timestamp << "] "
|
||||
stream << "[" << timestamp << "] <" << boost::this_thread::get_id() << "> "
|
||||
<< Logger::SeverityToString(entry.Severity) << "/" << entry.Facility << ": "
|
||||
<< entry.Message;
|
||||
|
||||
|
|
|
@ -137,7 +137,6 @@ void ConfigCompilerContext::ActivateItems(void)
|
|||
|
||||
Logger::Write(LogInformation, "config", "Activating config items in compilation unit '" + m_Unit + "'");
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) {
|
||||
ObjectLock olock(item);
|
||||
item->Commit();
|
||||
ConfigItem::Commit(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,6 +103,11 @@ vector<String> ConfigItem::GetParents(void) const
|
|||
return m_Parents;
|
||||
}
|
||||
|
||||
set<ConfigItem::WeakPtr> ConfigItem::GetChildren(void) const
|
||||
{
|
||||
return m_ChildObjects;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ConfigItem::Link(void) const
|
||||
{
|
||||
Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
|
||||
|
@ -151,42 +156,70 @@ void ConfigItem::InternalLink(const Dictionary::Ptr& dictionary) const
|
|||
*
|
||||
* @returns The DynamicObject that was created/updated.
|
||||
*/
|
||||
DynamicObject::Ptr ConfigItem::Commit(void)
|
||||
DynamicObject::Ptr ConfigItem::Commit(const ConfigItem::Ptr& self)
|
||||
{
|
||||
Logger::Write(LogDebug, "base", "Commit called for ConfigItem Type=" + GetType() + ", Name=" + GetName());
|
||||
String type, name;
|
||||
DynamicObject::Ptr dobj;
|
||||
vector<String> parents;
|
||||
Dictionary::Ptr properties;
|
||||
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
type = self->GetType();
|
||||
name = self->GetName();
|
||||
dobj = self->GetDynamicObject();
|
||||
parents = self->GetParents();
|
||||
properties = self->Link();
|
||||
}
|
||||
|
||||
Logger::Write(LogDebug, "base", "Commit called for ConfigItem Type=" + type + ", Name=" + name);
|
||||
|
||||
/* Make sure the type is valid. */
|
||||
DynamicType::Ptr dtype = DynamicType::GetByName(GetType());
|
||||
DynamicType::Ptr dtype = DynamicType::GetByName(type);
|
||||
|
||||
if (!dtype)
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Type '" + GetType() + "' does not exist."));
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Type '" + type + "' does not exist."));
|
||||
|
||||
/* Try to find an existing item with the same type and name. */
|
||||
pair<String, String> ikey = make_pair(GetType(), GetName());
|
||||
ItemMap::iterator it = m_Items.find(ikey);
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
if (it != m_Items.end()) {
|
||||
/* Unregister the old item from its parents. */
|
||||
ConfigItem::Ptr oldItem = it->second;
|
||||
ObjectLock olock(oldItem);
|
||||
oldItem->UnregisterFromParents();
|
||||
/* Try to find an existing item with the same type and name. */
|
||||
pair<String, String> ikey = make_pair(type, name);
|
||||
ItemMap::iterator it = m_Items.find(ikey);
|
||||
|
||||
/* Steal the old item's children. */
|
||||
m_ChildObjects = oldItem->m_ChildObjects;
|
||||
set<ConfigItem::WeakPtr> children;
|
||||
|
||||
if (it != m_Items.end()) {
|
||||
/* Unregister the old item from its parents. */
|
||||
ConfigItem::Ptr oldItem = it->second;
|
||||
ObjectLock olock(oldItem);
|
||||
oldItem->UnregisterFromParents();
|
||||
|
||||
/* Steal the old item's children. */
|
||||
children = oldItem->GetChildren();
|
||||
}
|
||||
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
self->m_ChildObjects = children;
|
||||
}
|
||||
|
||||
/* Register this item. */
|
||||
m_Items[ikey] = self;
|
||||
}
|
||||
|
||||
if (!dobj) {
|
||||
ObjectLock olock(dtype);
|
||||
dobj = dtype->GetObject(name);
|
||||
}
|
||||
|
||||
/* Register this item with its parents. */
|
||||
BOOST_FOREACH(const String& parentName, m_Parents) {
|
||||
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
||||
BOOST_FOREACH(const String& parentName, parents) {
|
||||
ConfigItem::Ptr parent = GetObject(type, parentName);
|
||||
ObjectLock olock(parent);
|
||||
parent->RegisterChild(GetSelf());
|
||||
parent->RegisterChild(self);
|
||||
}
|
||||
|
||||
/* Register this item. */
|
||||
m_Items[ikey] = GetSelf();
|
||||
|
||||
Dictionary::Ptr properties = Link();
|
||||
|
||||
/* Create a fake update in the format that
|
||||
* DynamicObject::ApplyUpdate expects. */
|
||||
Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
|
||||
|
@ -206,13 +239,6 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
update->Set("configTx", DynamicObject::GetCurrentTx());
|
||||
|
||||
/* Update or create the object and apply the configuration settings. */
|
||||
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
||||
|
||||
if (!dobj) {
|
||||
ObjectLock dlock(dtype);
|
||||
dobj = dtype->GetObject(GetName());
|
||||
}
|
||||
|
||||
bool was_null = false;
|
||||
|
||||
if (!dobj) {
|
||||
|
@ -227,7 +253,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
if (!was_null)
|
||||
dobj->ApplyUpdate(update, Attribute_Config);
|
||||
|
||||
m_DynamicObject = dobj;
|
||||
self->m_DynamicObject = dobj;
|
||||
|
||||
if (dobj->IsAbstract())
|
||||
dobj->Unregister();
|
||||
|
@ -237,7 +263,12 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
|
||||
/* We need to make a copy of the child objects because the
|
||||
* OnParentCommitted() handler is going to update the list. */
|
||||
set<ConfigItem::WeakPtr> children = m_ChildObjects;
|
||||
set<ConfigItem::WeakPtr> children;
|
||||
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
children = self->m_ChildObjects;
|
||||
}
|
||||
|
||||
/* notify our children of the update */
|
||||
BOOST_FOREACH(const ConfigItem::WeakPtr wchild, children) {
|
||||
|
@ -246,11 +277,10 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
if (!child)
|
||||
continue;
|
||||
|
||||
ObjectLock olock(child);
|
||||
child->OnParentCommitted();
|
||||
}
|
||||
|
||||
OnCommitted(GetSelf());
|
||||
OnCommitted(self);
|
||||
|
||||
return dobj;
|
||||
}
|
||||
|
@ -305,8 +335,17 @@ void ConfigItem::UnregisterFromParents(void)
|
|||
*/
|
||||
void ConfigItem::OnParentCommitted(void)
|
||||
{
|
||||
if (GetObject(GetType(), GetName()) == static_cast<ConfigItem::Ptr>(GetSelf()))
|
||||
Commit();
|
||||
ConfigItem::Ptr self;
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
self = GetSelf();
|
||||
|
||||
if (GetObject(self->GetType(), self->GetName()) != self)
|
||||
return;
|
||||
}
|
||||
|
||||
Commit(self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,10 +43,11 @@ public:
|
|||
String GetUnit(void) const;
|
||||
|
||||
vector<String> GetParents(void) const;
|
||||
set<ConfigItem::WeakPtr> GetChildren(void) const;
|
||||
|
||||
ExpressionList::Ptr GetExpressionList(void) const;
|
||||
|
||||
DynamicObject::Ptr Commit(void);
|
||||
static DynamicObject::Ptr Commit(const ConfigItem::Ptr& self);
|
||||
void Unregister(void);
|
||||
|
||||
void Dump(ostream& fp) const;
|
||||
|
|
|
@ -403,7 +403,7 @@ void ExternalCommandProcessor::EnableHostgroupSvcChecks(double, const vector<Str
|
|||
|
||||
HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
|
||||
BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
|
||||
Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
|
||||
service->SetEnableActiveChecks(true);
|
||||
|
@ -418,7 +418,7 @@ void ExternalCommandProcessor::DisableHostgroupSvcChecks(double, const vector<St
|
|||
|
||||
HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
|
||||
BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
|
||||
Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
|
||||
service->SetEnableActiveChecks(false);
|
||||
|
@ -433,7 +433,7 @@ void ExternalCommandProcessor::EnableServicegroupSvcChecks(double, const vector<
|
|||
|
||||
ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
|
||||
Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
|
||||
service->SetEnableActiveChecks(true);
|
||||
}
|
||||
|
@ -446,7 +446,7 @@ void ExternalCommandProcessor::DisableServicegroupSvcChecks(double, const vector
|
|||
|
||||
ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
|
||||
Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
|
||||
service->SetEnableActiveChecks(false);
|
||||
}
|
||||
|
@ -481,7 +481,7 @@ void ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks(double, const
|
|||
|
||||
ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
|
||||
Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + service->GetName() + "'");
|
||||
service->SetEnablePassiveChecks(true);
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ void ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks(double, const
|
|||
|
||||
ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
|
||||
Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + service->GetName() + "'");
|
||||
service->SetEnablePassiveChecks(true);
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ void ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks(double, const vec
|
|||
|
||||
HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
|
||||
BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
|
||||
Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + service->GetName() + "'");
|
||||
service->SetEnablePassiveChecks(true);
|
||||
|
@ -522,7 +522,7 @@ void ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks(double, const ve
|
|||
|
||||
HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
|
||||
BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
|
||||
Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + service->GetName() + "'");
|
||||
service->SetEnablePassiveChecks(false);
|
||||
|
@ -657,7 +657,7 @@ void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const vecto
|
|||
if (triggeredByLegacy != 0)
|
||||
triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
|
||||
BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
|
||||
Logger::Write(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
|
||||
Service::Ptr service = host->GetHostCheckService();
|
||||
if (service) {
|
||||
|
@ -686,7 +686,7 @@ void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const vector
|
|||
|
||||
set<Service::Ptr> services;
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
|
||||
BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
|
||||
services.insert(service);
|
||||
}
|
||||
|
@ -718,7 +718,7 @@ void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const ve
|
|||
|
||||
set<Service::Ptr> services;
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
|
||||
Host::Ptr host = service->GetHost();
|
||||
Service::Ptr hcService = host->GetHostCheckService();
|
||||
if (hcService)
|
||||
|
@ -745,7 +745,7 @@ void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const vec
|
|||
if (triggeredByLegacy != 0)
|
||||
triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||
BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
|
||||
Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
|
||||
(void) service->AddDowntime(arguments[6], arguments[7],
|
||||
Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
|
||||
|
|
|
@ -34,13 +34,18 @@ REGISTER_TYPE(Host, hostAttributes);
|
|||
|
||||
Host::Host(const Dictionary::Ptr& properties)
|
||||
: DynamicObject(properties)
|
||||
{
|
||||
HostGroup::InvalidateMembersCache();
|
||||
}
|
||||
{ }
|
||||
|
||||
void Host::OnInitCompleted(void)
|
||||
void Host::OnRegistrationCompleted(void)
|
||||
{
|
||||
UpdateSlaveServices();
|
||||
DynamicObject::OnRegistrationCompleted();
|
||||
|
||||
HostGroup::InvalidateMembersCache();
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
UpdateSlaveServices();
|
||||
}
|
||||
}
|
||||
|
||||
Host::~Host(void)
|
||||
|
@ -264,7 +269,7 @@ void Host::UpdateSlaveServices(void)
|
|||
}
|
||||
|
||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||
serviceItem->Commit();
|
||||
ConfigItem::Commit(serviceItem);
|
||||
|
||||
newServices->Set(name, serviceItem);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
const std::vector<icinga::Value>& arguments);
|
||||
|
||||
protected:
|
||||
void OnInitCompleted(void);
|
||||
void OnRegistrationCompleted(void);
|
||||
void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
|
|
|
@ -72,15 +72,23 @@ HostGroup::Ptr HostGroup::GetByName(const String& name)
|
|||
return dynamic_pointer_cast<HostGroup>(configObject);
|
||||
}
|
||||
|
||||
set<Host::Ptr> HostGroup::GetMembers(void) const
|
||||
set<Host::Ptr> HostGroup::GetMembers(const HostGroup::Ptr& self)
|
||||
{
|
||||
set<Host::Ptr> hosts;
|
||||
String name;
|
||||
|
||||
ValidateMembersCache();
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
name = self->GetName();
|
||||
}
|
||||
|
||||
set<Host::Ptr> hosts;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
BOOST_FOREACH(const Host::WeakPtr& hst, m_MembersCache[GetName()]) {
|
||||
|
||||
ValidateMembersCache();
|
||||
|
||||
BOOST_FOREACH(const Host::WeakPtr& hst, m_MembersCache[name]) {
|
||||
Host::Ptr host = hst.lock();
|
||||
|
||||
if (!host)
|
||||
|
@ -100,10 +108,11 @@ void HostGroup::InvalidateMembersCache(void)
|
|||
m_MembersCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Caller must hold m_Mutex.
|
||||
*/
|
||||
void HostGroup::ValidateMembersCache(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
if (m_MembersCacheValid)
|
||||
return;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
String GetNotesUrl(void) const;
|
||||
String GetActionUrl(void) const;
|
||||
|
||||
set<Host::Ptr> GetMembers(void) const;
|
||||
static set<Host::Ptr> GetMembers(const HostGroup::Ptr& self);
|
||||
static void InvalidateMembersCache(void);
|
||||
|
||||
private:
|
||||
|
|
|
@ -77,12 +77,11 @@ void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
|
|||
ProcessResult pr;
|
||||
|
||||
try {
|
||||
ObjectLock olock(ct.m_Process);
|
||||
pr = ct.m_Process->GetResult();
|
||||
} catch (...) {
|
||||
{
|
||||
ObjectLock olock(ct.m_Task);
|
||||
ct.m_Task->FinishException(boost::current_exception());
|
||||
}
|
||||
ObjectLock olock(ct.m_Task);
|
||||
ct.m_Task->FinishException(boost::current_exception());
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -94,10 +93,8 @@ void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
|
|||
result->Set("execution_start", pr.ExecutionStart);
|
||||
result->Set("execution_end", pr.ExecutionEnd);
|
||||
|
||||
{
|
||||
ObjectLock olock(ct.m_Task);
|
||||
ct.m_Task->FinishResult(result);
|
||||
}
|
||||
ObjectLock olock(ct.m_Task);
|
||||
ct.m_Task->FinishResult(result);
|
||||
}
|
||||
|
||||
ServiceState PluginCheckTask::ExitStatusToState(int exitStatus)
|
||||
|
|
|
@ -182,7 +182,7 @@ void Service::UpdateSlaveNotifications(void)
|
|||
}
|
||||
|
||||
ConfigItem::Ptr notificationItem = builder->Compile();
|
||||
notificationItem->Commit();
|
||||
ConfigItem::Commit(notificationItem);
|
||||
|
||||
newNotifications->Set(name, notificationItem);
|
||||
}
|
||||
|
|
|
@ -47,16 +47,21 @@ REGISTER_TYPE(Service, serviceAttributes);
|
|||
|
||||
Service::Service(const Dictionary::Ptr& serializedObject)
|
||||
: DynamicObject(serializedObject)
|
||||
{ }
|
||||
|
||||
void Service::OnRegistrationCompleted(void)
|
||||
{
|
||||
DynamicObject::OnRegistrationCompleted();
|
||||
|
||||
ServiceGroup::InvalidateMembersCache();
|
||||
Host::InvalidateServicesCache();
|
||||
Service::InvalidateDowntimesCache();
|
||||
Service::InvalidateCommentsCache();
|
||||
}
|
||||
|
||||
void Service::OnInitCompleted(void)
|
||||
{
|
||||
UpdateSlaveNotifications();
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
UpdateSlaveNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
Service::~Service(void)
|
||||
|
|
|
@ -248,7 +248,7 @@ public:
|
|||
void SetNextNotification(double time);
|
||||
|
||||
protected:
|
||||
virtual void OnInitCompleted(void);
|
||||
virtual void OnRegistrationCompleted(void);
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
|
|
|
@ -72,15 +72,23 @@ ServiceGroup::Ptr ServiceGroup::GetByName(const String& name)
|
|||
return dynamic_pointer_cast<ServiceGroup>(configObject);
|
||||
}
|
||||
|
||||
set<Service::Ptr> ServiceGroup::GetMembers(void) const
|
||||
set<Service::Ptr> ServiceGroup::GetMembers(const ServiceGroup::Ptr& self)
|
||||
{
|
||||
set<Service::Ptr> services;
|
||||
String name;
|
||||
|
||||
ValidateMembersCache();
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
name = self->GetName();
|
||||
}
|
||||
|
||||
set<Service::Ptr> services;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
BOOST_FOREACH(const Service::WeakPtr& svc, m_MembersCache[GetName()]) {
|
||||
|
||||
ValidateMembersCache();
|
||||
|
||||
BOOST_FOREACH(const Service::WeakPtr& svc, m_MembersCache[name]) {
|
||||
Service::Ptr service = svc.lock();
|
||||
|
||||
if (!service)
|
||||
|
@ -100,10 +108,11 @@ void ServiceGroup::InvalidateMembersCache(void)
|
|||
m_MembersCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Caller must hold m_Mutex.
|
||||
*/
|
||||
void ServiceGroup::ValidateMembersCache(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
if (m_MembersCacheValid)
|
||||
return;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
String GetNotesUrl(void) const;
|
||||
String GetActionUrl(void) const;
|
||||
|
||||
set<Service::Ptr> GetMembers(void) const;
|
||||
static set<Service::Ptr> GetMembers(const ServiceGroup::Ptr& self);
|
||||
static void InvalidateMembersCache(void);
|
||||
|
||||
private:
|
||||
|
|
|
@ -87,7 +87,7 @@ Endpoint::Ptr Endpoint::MakeEndpoint(const String& name, bool replicated, bool l
|
|||
endpointConfig->SetLocal(!replicated);
|
||||
endpointConfig->AddExpression("local", OperatorSet, local);
|
||||
|
||||
DynamicObject::Ptr object = endpointConfig->Compile()->Commit();
|
||||
DynamicObject::Ptr object = ConfigItem::Commit(endpointConfig->Compile());
|
||||
return dynamic_pointer_cast<Endpoint>(object);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue