diff --git a/objectstore/Action.hpp b/objectstore/Action.hpp index 8699f7f3830a7572917f302a6594529475b98dc1..4c47a2eeded21bd872f38091ea974e0632c14a43 100644 --- a/objectstore/Action.hpp +++ b/objectstore/Action.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Agent.hpp" +#include "AgentVisitor.hpp" #include "RootEntry.hpp" #include "RecallJob.hpp" #include "JobPool.hpp" @@ -149,11 +149,24 @@ private: Agent & m_agent; void collectGarbage(const std::string & agentName) { // When collecting the garbage of an agent, we have to iterate through its - // intended and owned objects, validate that they are still owned by the dead - // agent, and re-post them to the container where they should be (and ownership) - // is re-set to the container. - Agent ag(agentName, m_agent); - std::list<Agent::intentEntry> intendedObjects = ag.getIntentLog(); + // intended and owned objects, validate that they still exist, are owned by + // the dead agent, and re-post them to the container where they should be. + try { + // If the agent entry does not exist anymore, we're done. + AgentVisitor ag(agentName, m_agent); + std::list<AgentVisitor::intentEntry> intendedObjects = ag.getIntentLog(m_agent); + for (std::list<AgentVisitor::intentEntry>::iterator i=intendedObjects.begin(); + i != intendedObjects.end(); i++) { + switch (i->typeName) { + case "recallFIFO": + break; + case "RecallJob": + break; + case "jobPool": + breal; + } + } + } catch (...) {} } }; diff --git a/objectstore/Agent.cpp b/objectstore/Agent.cpp index 11d9fdef11e4e89dd314636eeec8c5f3a373b874..e987d37f81be7cd3232fd2073f4f55ab76e76276 100644 --- a/objectstore/Agent.cpp +++ b/objectstore/Agent.cpp @@ -16,16 +16,6 @@ cta::objectstore::Agent::Agent(ObjectStore & os, const std::string & typeName): setup(typeName); } -// Passive constructor, used for looking at existing agent records -cta::objectstore::Agent::Agent(const std::string & name, Agent & agent): - ObjectOps<serializers::Agent>(agent.objectStore(), name), - m_nextId(0), m_setupDone(true), m_creationDone(true), m_observerVersion(true) -{ - // check the presence of the entry - serializers::Agent as; - updateFromObjectStore(as, agent.getFreeContext()); -} - void cta::objectstore::Agent::setup(const std::string & typeName) { std::stringstream aid; // Get time @@ -216,27 +206,6 @@ cta::objectstore::ObjectStore & cta::objectstore::Agent::objectStore() { return ObjectOps<serializers::Agent>::objectStore(); } -std::string cta::objectstore::Agent::dump(Agent & agent) { - serializers::Agent as; - updateFromObjectStore(as, agent.getFreeContext()); - std::stringstream ret; - ret<< "<<<< Agent " << selfName() << " dump start" << std::endl - << "name=" << as.name() << std::endl - << "Ownership intent size=" << as.ownershipintent_size() << std::endl; - for (int i=0; i<as.ownershipintent_size(); i++) { - ret << "ownershipIntent[" << i << "]: name=" << as.ownershipintent(i).name() - << " type=" << as.ownershipintent(i).type() << std::endl; - } - ret << "Creation intent size=" << as.creationintent_size() << std::endl; - for (int i=0; i<as.creationintent_size(); i++) { - ret << "creationIntent[" << i << "]: name=" << as.creationintent(i).name() - << " type=" << as.creationintent(i).type() - << " container=" << as.creationintent(i).container() << std::endl; - } - ret<< ">>>> Agent " << selfName() << " dump end" << std::endl; - return ret.str(); -} - void cta::objectstore::Agent::heartbeat(Agent& agent) { ContextHandle & context = agent.getFreeContext(); serializers::Agent as; @@ -246,19 +215,5 @@ void cta::objectstore::Agent::heartbeat(Agent& agent) { uint64_t cta::objectstore::Agent::getHeartbeatCount(Agent& agent) { serializers::Agent as; updateFromObjectStore(as, agent.getFreeContext()); + return as.heartbeatcount(); } - - -cta::objectstore::AgentWatchdog::AgentWatchdog(const std::string& agentName, Agent& agent): -m_agentVisitor(agentName, agent) { - m_hearbeatCounter = m_agentVisitor.getHeartbeatCount(agent); -} - -bool cta::objectstore::AgentWatchdog::checkAlive(Agent& agent) { - uint64_t newHeartBeatCount = m_agentVisitor.getHeartbeatCount(agent); - if (newHeartBeatCount == m_hearbeatCounter && m_timer.secs() > 0.1) - return false; - m_hearbeatCounter = newHeartBeatCount; - return true; -} - diff --git a/objectstore/Agent.hpp b/objectstore/Agent.hpp index 789e24746a4ff3ebe614961ac76a48a753229e00..d636c88a77b0f649688cc0d53b0f9ee1f8ba0e7a 100644 --- a/objectstore/Agent.hpp +++ b/objectstore/Agent.hpp @@ -23,8 +23,6 @@ public: Agent(ObjectStore & os, const std::string & typeName); - Agent(const std::string & name, Agent & agent); - void setup(const std::string & typeName); class SetupNotDone: public cta::exception::Exception { @@ -102,15 +100,5 @@ private: static const size_t c_handleCount = 100; ContextHandleImplementation<myOS> m_contexts[c_handleCount]; }; - -class AgentWatchdog { -public: - AgentWatchdog(const std::string & agentName, Agent & agent); - bool checkAlive(Agent & agent); -private: - cta::utils::Timer m_timer; - Agent m_agentVisitor; - uint64_t m_hearbeatCounter; -}; }} \ No newline at end of file diff --git a/objectstore/AgentVisitor.hpp b/objectstore/AgentVisitor.hpp index 9430ecad163630f3531327af036791cc561d88bf..d7ef4df501a659f92ec3504e3d5a4aae99ca78eb 100644 --- a/objectstore/AgentVisitor.hpp +++ b/objectstore/AgentVisitor.hpp @@ -2,12 +2,165 @@ #include "ObjectOps.hpp" #include "objectstore/cta.pb.h" +#include <string> namespace cta { namespace objectstore { - class AgentVisitor: private ObjectOps<serializers::Agent> { +class AgentVisitor: private ObjectOps<serializers::Agent> { +public: + AgentVisitor(const std::string & name, Agent & agent): + ObjectOps<serializers::Agent>(agent.objectStore(), name) + { + // check the presence of the entry + serializers::Agent as; + updateFromObjectStore(as, agent.getFreeContext()); + } + + std::string name(Agent & agent) { + serializers::Agent as; + updateFromObjectStore(as, agent.getFreeContext()); + return as.name(); + } + + void removeFromIntent (std::string container, std::string name, + std::string typeName, Agent & agent) { + ContextHandle & context = agent.getFreeContext(); + serializers::Agent as; + lockExclusiveAndRead(as, context); + bool found; + do { + found = false; + for (int i=0; i<as.creationintent_size(); i++) { + if (container == as.creationintent(i).container() && + name == as.creationintent(i).name() && + typeName == as.creationintent(i).type()) { + found = true; + as.mutable_creationintent()->SwapElements(i, as.creationintent_size()-1); + as.mutable_creationintent()->RemoveLast(); + break; + } + } + } while (found); + write(as); + unlock(context); + } + + void removeFromOwnership(std::string name, std::string typeName, Agent & agent) { + serializers::Agent as; + ContextHandle & context = agent.getFreeContext(); + lockExclusiveAndRead(as, context); + bool found; + do { + found = false; + for (int i=0; i<as.ownershipintent_size(); i++) { + if (name == as.ownershipintent(i).name() && + typeName == as.ownershipintent(i).type()) { + found = true; + as.mutable_creationintent()->SwapElements(i, as.ownershipintent_size()-1); + as.mutable_creationintent()->RemoveLast(); + break; + } + } + } while (found); + write(as); + unlock(context); + } + + class intentEntry { + public: + intentEntry(const std::string & c, + const std::string & n, + const std::string & t):container(c), name(n), typeName(t) {} + std::string container; + std::string name; + std::string typeName; + }; + class ownershipEntry { + public: + ownershipEntry(const std::string & n, + const std::string & t):name(n), typeName(t) {} + std::string name; + std::string typeName; }; + std::list<intentEntry> getIntentLog(Agent & agent) { + serializers::Agent as; + updateFromObjectStore(as, agent.getFreeContext()); + std::list<intentEntry> ret; + for (int i=0; i<as.creationintent_size(); i++) { + ret.push_back(intentEntry(as.creationintent(i).container(), + as.creationintent(i).name(), + as.creationintent(i).type())); + } + return ret; + } + + std::list<ownershipEntry> getOwnershipLog(Agent & agent) { + serializers::Agent as; + updateFromObjectStore(as, agent.getFreeContext()); + std::list<ownershipEntry> ret; + for (int i=0; i<as.creationintent_size(); i++) { + ret.push_back(ownershipEntry(as.creationintent(i).name(), + as.creationintent(i).type())); + } + return ret; + } + + void remove(Agent & agent) { + removeOther(selfName()); + } + + uint64_t getHeartbeatCount(Agent& agent) { + serializers::Agent as; + updateFromObjectStore(as, agent.getFreeContext()); + return as.heartbeatcount(); + } + + std::string dump(Agent & agent) { + serializers::Agent as; + updateFromObjectStore(as, agent.getFreeContext()); + std::stringstream ret; + ret<< "<<<< Agent " << selfName() << " dump start" << std::endl + << "name=" << as.name() << std::endl + << "Ownership intent size=" << as.ownershipintent_size() << std::endl; + for (int i=0; i<as.ownershipintent_size(); i++) { + ret << "ownershipIntent[" << i << "]: name=" << as.ownershipintent(i).name() + << " type=" << as.ownershipintent(i).type() << std::endl; + } + ret << "Creation intent size=" << as.creationintent_size() << std::endl; + for (int i=0; i<as.creationintent_size(); i++) { + ret << "creationIntent[" << i << "]: name=" << as.creationintent(i).name() + << " type=" << as.creationintent(i).type() + << " container=" << as.creationintent(i).container() << std::endl; + } + ret<< ">>>> Agent " << selfName() << " dump end" << std::endl; + return ret.str(); + } + +}; + +class AgentWatchdog { +public: + AgentWatchdog(const std::string & agentName, Agent & agent): + m_agentVisitor(agentName, agent) { + m_hearbeatCounter = m_agentVisitor.getHeartbeatCount(agent); + } + + bool checkAlive(Agent & agent) { + uint64_t newHeartBeatCount = m_agentVisitor.getHeartbeatCount(agent); + if (newHeartBeatCount == m_hearbeatCounter && m_timer.secs() > 0.1) + return false; + m_hearbeatCounter = newHeartBeatCount; + return true; + } + +private: + cta::utils::Timer m_timer; + AgentVisitor m_agentVisitor; + uint64_t m_hearbeatCounter; +}; + + }} \ No newline at end of file diff --git a/objectstore/ObjectStructureDumper.hpp b/objectstore/ObjectStructureDumper.hpp index aadfc062340219b014c7f6ca15eedf964448295d..79bc106ddea1574dfa9a9cad8004fa84e0496599 100644 --- a/objectstore/ObjectStructureDumper.hpp +++ b/objectstore/ObjectStructureDumper.hpp @@ -20,7 +20,7 @@ public: ret << ar.dump(agent) << std::endl; std::list<std::string> agList = ar.getElements(agent); for (std::list<std::string>::iterator i=agList.begin(); i!=agList.end(); i++) { - Agent a(*i, agent); + AgentVisitor a(*i, agent); ret << a.dump(agent) << std::endl; } } catch (RootEntry::NotAllocatedEx &) {} diff --git a/objectstore/tapeResourceManagerTest.cpp b/objectstore/tapeResourceManagerTest.cpp index 4e62b37756237430aa1f745a8f3a7556ee45a71e..15ef01e1e8ae7e4a20a4a5112d373fc16f11ffe8 100644 --- a/objectstore/tapeResourceManagerTest.cpp +++ b/objectstore/tapeResourceManagerTest.cpp @@ -12,6 +12,7 @@ #include "AgentRegister.hpp" #include "RecallJob.hpp" #include "Register.hpp" +#include "AgentVisitor.hpp"