From d517f4add19266becdf3f50eec79123ba1fe3e32 Mon Sep 17 00:00:00 2001 From: Eric Cano <Eric.Cano@cern.ch> Date: Wed, 28 Jan 2015 18:57:54 +0100 Subject: [PATCH] Removed unused intent logs, implemented automatic agent registration with proper intent logging and added further dumps. --- objectstore/RootEntry.cpp | 140 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 objectstore/RootEntry.cpp diff --git a/objectstore/RootEntry.cpp b/objectstore/RootEntry.cpp new file mode 100644 index 0000000000..10f719c738 --- /dev/null +++ b/objectstore/RootEntry.cpp @@ -0,0 +1,140 @@ +#include "RootEntry.hpp" + +#include "Agent.hpp" + +// Initializer. +void RootEntry::init(ObjectStore & os) { + // check existence of root entry before creating it. We expect read to fail. + try { + os.read(s_rootEntryName); + throw cta::exception::Exception("In RootEntry::init: root entry already exists"); + } catch (...) {} + cta::objectstore::RootEntry res; + os.atomicOverwrite(s_rootEntryName, res.SerializeAsString()); +} +// construtor, when the backend store exists. +// Checks the existence and correctness of the root entry +RootEntry::RootEntry(Agent & agent): + ObjectOps<cta::objectstore::RootEntry>(agent.objectStore(), s_rootEntryName) { + // Check that the root entry is readable. + cta::objectstore::RootEntry res; + updateFromObjectStore(res, agent.getFreeContext()); +} + +// Get the name of the agent register (or exception if not available) +std::string RootEntry::getAgentRegister(Agent & agent) { + // Check if the agent register exists + cta::objectstore::RootEntry res; + updateFromObjectStore(res, agent.getFreeContext()); + // If the registry is defined, return it, job done. + if (res.agentregister().size()) + return res.agentregister(); + throw NotAllocatedEx("In RootEntry::getAgentRegister: agentRegister not yet allocated"); +} + +// Get the name of a (possibly freshly created) agent register +std::string RootEntry::allocateOrGetAgentRegister(Agent & agent) { + // Check if the agent register exists + try { + return getAgentRegister(agent); + } catch (NotAllocatedEx &) { + // If we get here, the agent register is not created yet, so we have to do it: + // lock the entry again, for writing + cta::objectstore::RootEntry res; + ContextHandle & context = agent.getFreeContext(); + lockExclusiveAndRead(res, context); + // If the registry is already defined, somebody was faster. We're done. + if (res.agentregister().size()) { + unlock(context); + return res.agentregister(); + } + // We will really create the register + // decide on the object's name + std::string arName (agent.nextId("agentRegister")); + // Record the agent in the intent log + res.add_agentregisterintentlog(arName); + // Commit the intents + write(res); + // The potential object can now be garbage collected if we die from here. + // Create the object, then lock. The name should be unique, so no race. + cta::objectstore::Register ars; + writeChild(arName, ars); + // If we lived that far, we can update the root entry to point to our + // new agent register, and remove the name from the intent log. + res.set_agentregister(arName); + res.mutable_agentregisterintentlog()->RemoveLast(); + write(res); + // release the lock, and return the register name + unlock(context); + return arName; + } +} + +// Get the name of the JobPool (or exception if not available) +std::string RootEntry::getJobPool(Agent & agent) { + // Check if the job pool exists + cta::objectstore::RootEntry res; + updateFromObjectStore(res, agent.getFreeContext()); + // If the registry is defined, return it, job done. + if (res.jobpool().size()) + return res.jobpool(); + throw NotAllocatedEx("In RootEntry::getJobPool: jobPool not yet allocated"); +} + +// Get the name of a (possibly freshly created) job pool +std::string RootEntry::allocateOrGetJobPool(Agent & agent) { + // Check if the job pool exists + try { + return getJobPool(agent); + } catch (NotAllocatedEx &) { + // If we get here, the job pool is not created yet, so we have to do it: + // lock the entry again, for writing + cta::objectstore::RootEntry res; + ContextHandle & context = agent.getFreeContext(); + lockExclusiveAndRead(res, context); + // If the registry is already defined, somebody was faster. We're done. + if (res.jobpool().size()) { + unlock(context); + return res.jobpool(); + } + // We will really create the register + // decide on the object's name + std::string jpName (agent.nextId("jobPool")); + // Record the agent in the intent log + agent.addToIntend(s_rootEntryName, jpName, "jobPool"); + // The potential object can now be garbage collected if we die from here. + // Create the object, then lock. The name should be unique, so no race. + cta::objectstore::jobPool jps; + jps.set_migration(""); + jps.set_recall(""); + writeChild(jpName, jps); + // If we lived that far, we can update the root entry to point to our + // new agent register, and remove the name from the intent log. + res.set_jobpool(jpName); + write(res); + // release the lock, and return the register name + unlock(context); + // Clear intent log + agent.removeFromIntent(s_rootEntryName, jpName, "jobPool"); + return jpName; + } +} + +// Dump the root entry +std::string RootEntry::dump (Agent & agent) { + std::stringstream ret; + cta::objectstore::RootEntry res; + updateFromObjectStore(res, agent.getFreeContext()); + ret << "<<<< Root entry dump start" << std::endl; + if (res.has_agentregister()) ret << "agentRegister=" << res.agentregister() << std::endl; + for (int i=0; i<res.agentregisterintentlog_size(); i++) { + ret << "agentRegisterIntentLog=" << res.agentregisterintentlog(i) << std::endl; + } + if (res.has_jobpool()) ret << "jobPool=" << res.jobpool() << std::endl; + if (res.has_driveregister()) ret << "driveRegister=" << res.driveregister() << std::endl; + if (res.has_taperegister()) ret << "tapeRegister=" << res.taperegister() << std::endl; + ret << ">>>> Root entry dump start" << std::endl; + return ret.str(); +} + +const std::string RootEntry::s_rootEntryName("root"); \ No newline at end of file -- GitLab