From cfce4812eeafd2d1658199bbda61c0bdab207e3c Mon Sep 17 00:00:00 2001 From: Ruud Overeem <overeem@astron.nl> Date: Wed, 29 Nov 2006 22:06:14 +0000 Subject: [PATCH] BugID: 679 Some small modification to support SCHEDULE messages better. --- .gitattributes | 1 - .../include/APL/APLCommon/ChildControl.h | 5 + .../include/APL/APLCommon/ControllerInfo.h | 2 + MAC/APL/APLCommon/src/APLCommon.dpl | 17 ---- MAC/APL/APLCommon/src/ChildControl.cc | 93 +++++++++++++++++-- MAC/APL/APLCommon/src/ParentControl.cc | 35 +++++-- MAC/APL/APLCommon/src/PropertySetAnswer.cc | 4 +- 7 files changed, 125 insertions(+), 32 deletions(-) delete mode 100644 MAC/APL/APLCommon/src/APLCommon.dpl diff --git a/.gitattributes b/.gitattributes index 2bf801d760f..425ff7e3826 100644 --- a/.gitattributes +++ b/.gitattributes @@ -231,7 +231,6 @@ LCS/Common/src/Common-Model.cat -text MAC/APL/APLCommon/Makefile.am -text svneol=native#application/octet-stream MAC/APL/APLCommon/bootstrap -text svneol=native#application/octet-stream MAC/APL/APLCommon/configure.in -text svneol=native#application/octet-stream -MAC/APL/APLCommon/src/APLCommon.dpl -text svneol=native#application/octet-stream MAC/APL/APLCommon/src/Makefile.am -text svneol=native#application/octet-stream MAC/APL/APLCommon/src/StartDaemon_Protocol.prot -text svneol=native#application/octet-stream MAC/APL/DEPENDENCIES -text svneol=native#application/octet-stream diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/ChildControl.h b/MAC/APL/APLCommon/include/APL/APLCommon/ChildControl.h index 5870f085223..5052db52809 100644 --- a/MAC/APL/APLCommon/include/APL/APLCommon/ChildControl.h +++ b/MAC/APL/APLCommon/include/APL/APLCommon/ChildControl.h @@ -104,6 +104,11 @@ public: const string& aName, OTDBtreeIDType anObsID = 0, uint16 aCntlrType = CNTLRTYPE_NO_TYPE); + bool rescheduleChilds(time_t aStartTime, + time_t aStopTime, + const string& aName, + OTDBtreeIDType anObsID = 0, + uint16 aCntlrType = CNTLRTYPE_NO_TYPE); uint32 countChilds (OTDBtreeIDType anObsID = 0, uint16 aCntlrType = CNTLRTYPE_NO_TYPE); diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/ControllerInfo.h b/MAC/APL/APLCommon/include/APL/APLCommon/ControllerInfo.h index dba91064b74..5e3cd2c41a7 100644 --- a/MAC/APL/APLCommon/include/APL/APLCommon/ControllerInfo.h +++ b/MAC/APL/APLCommon/include/APL/APLCommon/ControllerInfo.h @@ -83,6 +83,8 @@ private: CTState::CTstateNr currentState; // the state the controller has time_t establishTime; // time the current state was reached uint16 result; // error nr of last action + time_t startTime; // time the controller must be active + time_t stopTime; // time the controller must be stopped // --- for use in action list --- time_t retryTime; // time the request must be retried uint32 nrRetries; // nr of retries performed diff --git a/MAC/APL/APLCommon/src/APLCommon.dpl b/MAC/APL/APLCommon/src/APLCommon.dpl deleted file mode 100644 index 941bbdf9d81..00000000000 --- a/MAC/APL/APLCommon/src/APLCommon.dpl +++ /dev/null @@ -1,17 +0,0 @@ -# ascii dump of database - -# DpType -TypeName -TAplStartDaemon.TAplStartDaemon 1#1 - command 25#2 - status 21#3 -TAplLogicalDevice.TAplLogicalDevice 1#1 - command 25#2 - status 21#9 - state 25#4 - prepareTime 21#10 - startTime 21#11 - stopTime 21#12 - __childs 9#8 - claimTime 21#13 - version 25#14 diff --git a/MAC/APL/APLCommon/src/ChildControl.cc b/MAC/APL/APLCommon/src/ChildControl.cc index b52583ded34..80cfb69f37b 100644 --- a/MAC/APL/APLCommon/src/ChildControl.cc +++ b/MAC/APL/APLCommon/src/ChildControl.cc @@ -205,6 +205,7 @@ bool ChildControl::startChild (uint16 aCntlrType, if (hostname != GCF::Common::myHostname(false) && hostname != GCF::Common::myHostname(true)) { APLUtilities::remoteCopy(cntlrSetName, hostname, cntlrSetName); + APLUtilities::remoteCopy(baseSetName, hostname, baseSetName); } } @@ -224,6 +225,8 @@ bool ChildControl::startChild (uint16 aCntlrType, ci.retryTime = 0; ci.nrRetries = 0; ci.result = CT_RESULT_NO_ERROR; + ci.startTime = 0; // only used for reschedule + ci.stopTime = 0; // only used for reschedule // Update our administration. itsCntlrList->push_back(ci); @@ -235,6 +238,7 @@ bool ChildControl::startChild (uint16 aCntlrType, // Trigger statemachine. if (itsListener) { itsActionTimer = itsListener->setTimer(0.0); + LOG_DEBUG_STR("ACTIONTIMER=" << itsActionTimer); } LOG_TRACE_COND_STR ("Scheduled start of " << cntlrName << " for obs " << anObsID); @@ -273,7 +277,7 @@ void ChildControl::startChildControllers() startChild(childCntlrType, treeID, instanceNr, - myHostname(true)); + childhostname); // Note: controller is now in state NO_STATE/CONNECTED (C/R) LOG_DEBUG_STR("Requested start of " << childCntlrName); @@ -314,20 +318,76 @@ bool ChildControl::requestState (CTState::CTstateNr aState, if (!(checkName && iter->cntlrName != aName) && !(checkID && iter->obsID != anObsID) && !(checkType && iter->cntlrType != aCntlrType)) { - // send request to child + + // update controllerinfo to requested state and make an action of it. iter->requestedState = aState; iter->requestTime = currentTime; iter->result = CT_RESULT_NO_ERROR; iter->nrRetries = 0; iter->retryTime = 0; - - // add it to the actionlist itsActionList.push_back(*iter); } iter++; } + itsTimerPort.cancelTimer(itsActionTimer); itsActionTimer = itsTimerPort.setTimer(0.0); // invoke _processActionList + LOG_DEBUG_STR("ACTIONTIMER=" << itsActionTimer); + + return (true); +} + +// +// rescheduleChilds(startTime, stopTime, [name], [observation], [type]) +// +// Sends a reschedule request to the given child or childs. +// +bool ChildControl::rescheduleChilds (time_t aStartTime, + time_t aStopTime, + const string& aName, + OTDBtreeIDType anObsID, + uint16 aCntlrType) +{ + CTState cts; + LOG_TRACE_FLOW_STR("reschedule(" << aStartTime << "," + << aStopTime << "," + << aName <<","<< anObsID <<","<< aCntlrType <<")" ); + + bool checkName = (aName != ""); + bool checkID = (anObsID != 0); + bool checkType = (aCntlrType != CNTLRTYPE_NO_TYPE); + time_t currentTime = time(0); + + CIiter iter = itsCntlrList->begin(); + const_CIiter end = itsCntlrList->end(); + while (iter != end) { + // count the child when x has to be checked and matches: + // id==id checkID count_it + // Y Y Y + // Y N Y + // N Y N --> checkID && id!=id + // N N Y + if (!(checkName && iter->cntlrName != aName) && + !(checkID && iter->obsID != anObsID) && + !(checkType && iter->cntlrType != aCntlrType)) { + // remember the reschedule. + iter->startTime = aStartTime; + iter->stopTime = aStopTime; + // don't change state of original, it's an interim state. + ControllerInfo cntlrCopy(*iter); + cntlrCopy.requestedState = CTState::SCHEDULED; + cntlrCopy.requestTime = currentTime; + cntlrCopy.result = CT_RESULT_NO_ERROR; + cntlrCopy.nrRetries = 0; + cntlrCopy.retryTime = 0; + itsActionList.push_back(cntlrCopy); // TODO: push_front???? + } + + iter++; + } + itsTimerPort.cancelTimer(itsActionTimer); + itsActionTimer = itsTimerPort.setTimer(0.0); // invoke _processActionList + LOG_DEBUG_STR("ACTIONTIMER=" << itsActionTimer); return (true); } @@ -480,6 +540,10 @@ void ChildControl::_processActionList() { LOG_TRACE_FLOW("_processActionList()"); + // always cancel timer that brought me here. + itsTimerPort.cancelTimer(itsActionTimer); + itsActionTimer = 0; + uint32 nrActions = itsActionList.size(); // prevents handling rescheduled actions // when list is empty return; if (!nrActions) { @@ -493,7 +557,7 @@ void ChildControl::_processActionList() time_t currentTime = time(0); CIiter action = itsActionList.begin(); while (nrActions > 0) { - // don't process (rescheduled) action that lay in the future + // don't process (rescheduled) action that lays in the future if (action->retryTime > currentTime) { // retry in future? LOG_DEBUG_STR("parking:" << action->cntlrName << "->" << cts.name(action->requestedState) << " because its too early"); @@ -620,6 +684,16 @@ void ChildControl::_processActionList() } break; + case CTState::SCHEDULED: + { + CONTROLScheduleEvent request; + request.cntlrName = controller->cntlrName; + request.startTime = controller->startTime; + request.stopTime = controller->stopTime; + controller->port->send(request); + } + break; + case CTState::FINISHED: { CONTROLQuitEvent request; @@ -638,7 +712,9 @@ void ChildControl::_processActionList() } if (itsActionList.size()) { // when unhandled actions in list + itsTimerPort.cancelTimer(itsActionTimer); itsActionTimer = itsTimerPort.setTimer(1.0); // restart timer + LOG_DEBUG_STR("ACTIONTIMER=" << itsActionTimer); } } @@ -954,12 +1030,12 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, case F_TIMER: { GCFTimerEvent& timerEvent = static_cast<GCFTimerEvent&>(event); + LOG_DEBUG_STR("TIMERID=" << timerEvent.id); if (timerEvent.id == itsGarbageTimer) { itsGarbageTimer = 0; _doGarbageCollection(); } else { - itsActionTimer = 0; _processActionList(); } } @@ -1029,6 +1105,7 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, controller->requestedState = cts.stateNr(msg.curState); controller->currentState = cts.stateNr(msg.curState); controller->hostname = msg.hostname; + controller->port = &port; LOG_DEBUG_STR("Updated info of reconnected controller " << msg.cntlrName); } @@ -1075,6 +1152,10 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, } break; + case CONTROL_SCHEDULED: + // do nothing, is not a state change. + break; + case CONTROL_FINISH: { CONTROLFinishEvent msg(event); _setEstablishedState(msg.cntlrName, CTState::FINISH, time(0), diff --git a/MAC/APL/APLCommon/src/ParentControl.cc b/MAC/APL/APLCommon/src/ParentControl.cc index a333a651080..0937cdee9d6 100644 --- a/MAC/APL/APLCommon/src/ParentControl.cc +++ b/MAC/APL/APLCommon/src/ParentControl.cc @@ -66,7 +66,7 @@ static stateFlow stateFlowTable[] = { { CONTROL_FINISH, CTState::RELEASED, CTState::FINISHED }, { CONTROL_FINISHED, CTState::RELEASED, CTState::FINISHED }, // { CONTROL_FINISH, CTState::ANYSTATE, CTState::FINISHED }, -// { CONTROL_FINISHED, CTState::ANYSTATE, CTState::FINISHED }, + { CONTROL_FINISHED, CTState::FINISH, CTState::FINISHED }, { CONTROL_RESYNCED, CTState::ANYSTATE, CTState::ANYSTATE }, { CONTROL_SCHEDULE, CTState::ANYSTATE, CTState::ANYSTATE }, { CONTROL_QUIT, CTState::ANYSTATE, CTState::FINISH }, @@ -208,19 +208,19 @@ bool ParentControl::activateObservationTimers(const string& cntlrName, } // set or reset the real timers. + itsTimerPort.cancelTimer(parent->startTimer); if (startDiff.seconds() > 0) { parent->startTimer = itsTimerPort.setTimer((double)startDiff.seconds()); } else { - itsTimerPort.cancelTimer(parent->startTimer); parent->startTimer = 0; } + itsTimerPort.cancelTimer(parent->stopTimer); if (stopDiff.seconds() > 0) { parent->stopTimer = itsTimerPort.setTimer((double)stopDiff.seconds()); } else { - itsTimerPort.cancelTimer(parent->stopTimer); parent->stopTimer = 0; } @@ -467,7 +467,7 @@ bool ParentControl::_confirmState(uint16 signal, if (result != CT_RESULT_NO_ERROR) { parent->failed = true; - LOG_DEBUG_STR(cntlrName << " DID NOT reach the " << + LOG_ERROR_STR(cntlrName << " DID NOT reach the " << cts.name(requestedState(signal)) << " state, error=" << result); return (false); } @@ -787,8 +787,26 @@ GCFEvent::TResult ParentControl::operational(GCFEvent& event, cts.name(parent->requestedState)); } + if (event.signal == CONTROL_SCHEDULE) { // reschedule request? + CONTROLScheduleEvent schedMsg(event); + if (parent->stopTimer) { // do we keep track of the time? + activateObservationTimers(parent->name, // yes + from_time_t(schedMsg.startTime), + from_time_t(schedMsg.stopTime)); + // don't bother maintask with reschedule. + CONTROLScheduledEvent answer; + answer.cntlrName = schedMsg.cntlrName; + answer.result = CT_RESULT_NO_ERROR; + parent->port->send(answer); + return (GCFEvent::HANDLED); + } + // maintask does not use my timers, just pass through the event. + itsMainTaskPort->sendBack(schedMsg); + return (GCFEvent::HANDLED); + } + // When we were resyncing just continue what we were trying to do. - if (event.signal != CONTROL_RESYNCED && event.signal != CONTROL_SCHEDULED) { + if (event.signal != CONTROL_RESYNCED && event.signal != CONTROL_SCHEDULE) { // use stateFlowTable to determine the required state. parent->requestedState = requestedState(event.signal); } @@ -871,7 +889,11 @@ GCFEvent::TResult ParentControl::operational(GCFEvent& event, PIiter parent = findParent(msg.cntlrName); if (isParent(parent)) { // note do not register this state, it is not a real state - parent->port->send(msg); + LOG_INFO_STR("Controller " << msg.cntlrName << " is resynced"); + } + else { + LOG_WARN_STR("Received RESYNCED message from unknown controller " + << msg.cntlrName); } } break; @@ -883,6 +905,7 @@ GCFEvent::TResult ParentControl::operational(GCFEvent& event, PIiter parent = findParent(msg.cntlrName); if (isParent(parent)) { // note do not register this state, it is not a real state + LOG_DEBUG_STR("Passing SCHEDULED event to parent ocntroller"); parent->port->send(msg); } } diff --git a/MAC/APL/APLCommon/src/PropertySetAnswer.cc b/MAC/APL/APLCommon/src/PropertySetAnswer.cc index 2716d8b971f..b8580d56429 100644 --- a/MAC/APL/APLCommon/src/PropertySetAnswer.cc +++ b/MAC/APL/APLCommon/src/PropertySetAnswer.cc @@ -35,12 +35,12 @@ PropertySetAnswer::PropertySetAnswer(PropertySetAnswerHandlerInterface& handler) GCFAnswer(), m_handler(handler) { - LOG_DEBUG(formatString("PropertySetAnswer::PropertySetAnswer")); + LOG_DEBUG("PropertySetAnswer::PropertySetAnswer"); } PropertySetAnswer::~PropertySetAnswer() { - LOG_DEBUG(formatString("PropertySetAnswer::~PropertySetAnswer")); + LOG_DEBUG("PropertySetAnswer::~PropertySetAnswer"); } void PropertySetAnswer::handleAnswer(GCFEvent& answer) -- GitLab