diff --git a/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc b/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc deleted file mode 100644 index e12187d34dd7da656846715b8e5f8b91f4fa7146..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc +++ /dev/null @@ -1,848 +0,0 @@ -//# ChildControl.cc: one line description -//# -//# Copyright (C) 2006 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ - -//# Always #include <lofar_config.h> first! -#include <lofar_config.h> - -//# Includes -#include <Common/LofarLogger.h> -#include <APS/ParameterSet.h> -#include <MainCU/MACScheduler/ChildControl.h> -#include <GCF/GCF_ServiceInfo.h> -#include <GCF/Utils.h> -#include <APL/APLCommon/APLUtilities.h> -#include <APL/APLCommon/Controller_Protocol.ph> -#include <APL/APLCommon/StartDaemon_Protocol.ph> - -namespace LOFAR { - using namespace GCF::TM; - using namespace APLCommon; - using namespace ACC::APS; - namespace MainCU { - -//-------------------------- creation and destroy --------------------------- - -ChildControl* ChildControl::instance() -{ - static ChildControl* theirChildControl; - - if (theirChildControl == 0) { - theirChildControl = new ChildControl(); - } - return (theirChildControl); -} - -// -// ChildControl() -// -ChildControl::ChildControl() : - GCFTask ((State)&ChildControl::initial, "ChildControl"), - itsListener (0), - itsStartDaemonMap (), - itsStartupRetryInterval (10), - itsMaxStartupRetries (5), - itsCntlrList (), - itsActionList (), - itsCompletionTimer (0), - itsCompletionPort (0) -{ - // Log the protocols I use. - registerProtocol(CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_signalnames); - registerProtocol(STARTDAEMON_PROTOCOL,STARTDAEMON_PROTOCOL_signalnames); - - // adopt optional redefinition of startup-retry settings - if (globalParameterSet()->isDefined("ChildControl.StartupRetryInterval")) { - itsStartupRetryInterval = globalParameterSet()-> - getInt32("ChildControl.StartupRetryInterval"); - } - if (globalParameterSet()->isDefined("ChildControl.MaxStartupRetries")) { - itsStartupRetryInterval = globalParameterSet()-> - getInt32("ChildControl.MaxStartupRetries"); - } -} - -// -// ~ChildControl -// -ChildControl::~ChildControl() -{ - // close Listener - if (itsListener) { - itsListener->close(); - delete itsListener; - } - - // close all connections with the startDaemons. - map <string, GCFTCPPort*>::iterator iter = itsStartDaemonMap.begin(); - map <string, GCFTCPPort*>::const_iterator end = itsStartDaemonMap.end(); - while (iter != end) { - iter->second->close(); - iter++; - } - itsStartDaemonMap.clear(); - - // clear controller list. - itsCntlrList.clear(); - - // clear action list. - itsActionList.clear(); -} - -// -// openService(servicename, instanceNr) -// -// Starts the listener for the childs under the given name. -// -void ChildControl::openService(const string& aServiceName, - uint32 instanceNr) -{ - // can't set name only once - if (itsListener) { - return; - } - - itsListener = new GCFTCPPort(*this, aServiceName, GCFPortInterface::MSPP, - STARTDAEMON_PROTOCOL); - ASSERTSTR(itsListener, "Can't create a listener port for my children"); - - itsListener->setInstanceNr (instanceNr); - itsListener->open(); -} - -// -// startChild (name, obsId, aCntlType, instanceNr, hostname) -// -bool ChildControl::startChild (const string& aName, - OTDB::treeIDType anObsID, - const string& aCntlrType, - uint32 instanceNr, - const string& hostname) -{ - // first check if child already exists - if (findController(aName) != itsCntlrList.end()) { - return (false); - } - - // make sure there is a parameterSet for the program. - if (aCntlrType != CNTLRTYPE_OBSERVATIONCTRL) { - // search observation-parset for controller name and determine prefix - string baseSetName = formatString("%s/Observation_%d", - LOFAR_SHARE_LOCATION, anObsID); - LOG_DEBUG_STR ("Reading parameterfile: " << baseSetName); - ParameterSet wholeSet (baseSetName); - ParameterSet::iterator iter = wholeSet.begin(); - ParameterSet::iterator end = wholeSet.end(); - while (iter != end) { - // search a parameter that is meant for this controller - // to determine the position of the controller in the tree. - if (keyName(moduleName(iter->first)) == aName) { - string cntlrSetName = formatString("%s/%s", LOFAR_SHARE_LOCATION, - aName.c_str()); - LOG_DEBUG_STR("Creating parameterfile: " << cntlrSetName); - ParameterSet cntlrSet = wholeSet.makeSubset(moduleName(iter->first)); - cntlrSet.add("prefix", moduleName(iter->first)); - cntlrSet.writeFile (cntlrSetName); - break; - } - iter++; - } - if (iter == end) { // could not create a parameterset, report failure. - LOG_ERROR_STR("No parameter information found for controller " << aName << - " in file " << baseSetName << ". Cannot start controller!"); - return (false); - } - } - - // Alright, child does not exist yet. - // construct structure with all information - ControllerInfo ci; - ci.name = aName; - ci.instanceNr = instanceNr; - ci.obsID = anObsID; - ci.cntlrType = aCntlrType; - ci.port = 0; - ci.hostname = hostname; - ci.requestedState = LDState::CONNECTED; - ci.requestTime = time(0); - ci.currentState = LDState::NOSTATE; - ci.establishTime = 0; - ci.retryTime = 0; - ci.nrRetries = 0; - - // Update our administration. - itsCntlrList.push_back(ci); - - // Add it to the action list. - itsActionList.push_back(ci); - - // Trigger statemachine. - if (itsListener) { - itsActionTimer = itsListener->setTimer(0.0); - } - - LOG_TRACE_COND_STR ("Scheduled start of " << aName << " for obs " << anObsID); - - return (true); -} - -// -// requestState(state, [name], [observation], [type]) -// -// Sends a state-change request to the given child or childs. -// -bool ChildControl::requestState (LDState::LDstateNr aState, - const string& aName, - OTDB::treeIDType anObsID, - const string& aCntlrType) -{ - bool checkName = (aName != ""); - bool checkID = (anObsID != 0); - bool checkType = (aCntlrType != CNTLRTYPE_NO_TYPE); - time_t currentTime = time(0); - -// stateChangeEvent request; -// request.newState = aState; -// request.time = currentTime; - - 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->name != aName) && - !(checkID && iter->obsID != anObsID) && - !(checkType && iter->cntlrType != aCntlrType)) { - // send request to child - iter->requestedState = aState; - iter->requestTime = currentTime; -// iter->port.send(request); - } - - iter++; - } - - return (true); -} - -// -// getCurrentState(name) -// -// Returns the current state of the given controller. -// -LDState::LDstateNr ChildControl::getCurrentState (const string& aName) -{ - CIiter controller = findController(aName); - if (controller == itsCntlrList.end()) { - return (LDState::NOSTATE); - } - - return (controller->currentState); -} - -// -// getRequestedState(name) -// -// Returns the requested state of the given controller. -// -LDState::LDstateNr ChildControl::getRequestedState (const string& aName) -{ - CIiter controller = findController(aName); - if (controller == itsCntlrList.end()) { - return (LDState::NOSTATE); - } - - return (controller->requestedState); -} - -// -// countChilds([obsid],[cntlrtype]) -// -// Count the number of childs. The count can be limited to an -// observation or an controllertype or both. -// -uint32 ChildControl::countChilds (OTDB::treeIDType anObsID, - const string& aCntlrType) -{ - bool checkID = (anObsID != 0); - bool checkType = (aCntlrType != CNTLRTYPE_NO_TYPE); - - if (!checkID && !checkType) { - return (itsCntlrList.size()); - } - - uint32 count = 0; - const_CIiter iter = itsCntlrList.begin(); - const_CIiter end = itsCntlrList.end(); - while (iter != end) { - if (!(checkID && iter->obsID != anObsID) && - !(checkType && iter->cntlrType != aCntlrType)) { - count++; - } - - iter++; - } - - return (count); -} - - -// -// getPendingRequest ([name], [observation], [type]) -// -// Returns a vector with all requests that are not confirmed by the -// childs. -// -vector<ChildControl::StateInfo> -ChildControl::getPendingRequest (const string& aName, - OTDB::treeIDType anObsID, - const string& aCntlrType) -{ - vector<ChildControl::StateInfo> resultVec; - - bool checkName = (aName != ""); - bool checkID = (anObsID != 0); - bool checkType = (aCntlrType != CNTLRTYPE_NO_TYPE); - - const_CIiter iter = itsCntlrList.begin(); - const_CIiter end = itsCntlrList.end(); - while (iter != end) { - if (!(checkName && iter->name != aName) && - !(checkID && iter->obsID != anObsID) && - !(checkType && iter->cntlrType != aCntlrType) && - (iter->requestedState != iter->currentState)) { - // add info to vector - StateInfo si; - si.name = iter->name; - si.cntlrType = iter->cntlrType; - si.isConnected = (iter->port != 0); - si.requestedState = iter->requestedState; - si.requestTime = iter->requestTime; - si.currentState = iter->currentState; - si.establishTime = iter->establishTime; - resultVec.push_back(si); - } - iter++; - } - - return (resultVec); -} - -// -// getCompletedStates (lastPollTime) -// -// Returns a vector with all requests that are completed since lastPollTime -// -vector<ChildControl::StateInfo> -ChildControl::getCompletedStates (time_t lastPollTime) -{ - vector<ChildControl::StateInfo> resultVec; - - const_CIiter iter = itsCntlrList.begin(); - const_CIiter end = itsCntlrList.end(); - while (iter != end) { - if (iter->establishTime > lastPollTime) { - // add info to vector - StateInfo si; - si.name = iter->name; - si.cntlrType = iter->cntlrType; - si.isConnected = (iter->port != 0); - si.requestedState = iter->requestedState; - si.requestTime = iter->requestTime; - si.currentState = iter->currentState; - si.establishTime = iter->establishTime; - resultVec.push_back(si); - } - iter++; - } - - return (resultVec); -} - -// -------------------- PRIVATE ROUTINES -------------------- - -// -// findController (name) -// -ChildControl::CIiter ChildControl::findController(const string& aName) -{ - CIiter iter = itsCntlrList.begin(); - const_CIiter end = itsCntlrList.end(); - - while (iter != end && iter->name != aName) { - iter++; - } - return (iter); -} - -// -// _processActionList() -// -// Walks through the actionlist and tries to process the actions. -// -void ChildControl::_processActionList() -{ - uint32 nrActions = itsActionList.size(); // prevents handling rescheduled actions - // when list is empty return; - if (!nrActions) { - return; - } - - LOG_TRACE_VAR_STR("Found " << nrActions << " actions in list"); - - // Walk through the action list - time_t currentTime = time(0); - CIiter action = itsActionList.begin(); - while (nrActions > 0) { - // don't process (rescheduled) action that lay in the future - if (action->retryTime > currentTime) { - itsActionList.push_back(*action); // add at back - action++; // hop to next - itsActionList.pop_front(); // remove at front. - nrActions--; // one less to handle. - continue; - } - - // search if corresponding controller exists - CIiter controller = findController(action->name); - if (controller == itsCntlrList.end()) { - LOG_WARN_STR("Controller " << action->name << - " not in administration, discarding request for state " << - action->requestedState); - action++; // hop to next - itsActionList.pop_front(); // remove 'handled' action. - nrActions--; // one less to handle. - continue; - } - - // found an action that should be handled now. - switch (action->requestedState) { - case LDState::CONNECTED: // start program, wait for CONNECTED msgs of child - { - // first check if connection if StartDaemon is made - SDiter startDaemon = itsStartDaemonMap.find(action->hostname); - if (startDaemon == itsStartDaemonMap.end() || - !startDaemon->second->isConnected()) { - LOG_TRACE_COND_STR("Startdaemon for " << action->hostname << - " not yet connected, defering startup command for " - << action->cntlrType << ":" << action->obsID); - // if not SDport at all for this host, create one first - if (startDaemon == itsStartDaemonMap.end()) { - itsStartDaemonMap[action->hostname] = new GCFTCPPort(*this, - MAC_SVCMASK_STARTDAEMON, - GCFPortInterface::SAP, - STARTDAEMON_PROTOCOL); - itsStartDaemonMap[action->hostname]->setHostName(action->hostname); - } - itsStartDaemonMap[action->hostname]->open(); - // leave action in list until connection with SD is made - itsActionList.push_back(*action); - break; - } - - // There is an connection with the startDaemon - if (action->nrRetries < itsMaxStartupRetries) { // retries left? - LOG_DEBUG_STR("Requesting start of " << action->name << " at " - << action->hostname); - STARTDAEMONCreateEvent startRequest; - startRequest.cntlrType = action->cntlrType; - startRequest.cntlrName = action->name; - startRequest.parentHost = GCF::Common::myHostname(); - startRequest.parentService = itsListener->makeServiceName(); - startDaemon->second->send(startRequest); - - // we don't know if startup is successful, reschedule startup - // over x seconds for safety. Note: when a successful startup - // is received the rescheduled action is removed. -// action->retryTime = time(0) + itsStartupRetryInterval; -// action->nrRetries++; -// itsActionList.push_back(*action); // reschedule -// ... Parent is responsible for rescheduling! ... - } - else { - LOG_WARN_STR ("Could not start controller " << action->name << - " for observation " << action->obsID << - ", giving up."); - } - } - break; - - case LDState::CLAIMED: - { - CONTROLClaimEvent request; - request.cntlrName = controller->name; - controller->port->send(request); - } - break; - - case LDState::PREPARED: - { - CONTROLPrepareEvent request; - request.cntlrName = controller->name; - controller->port->send(request); - } - break; - - case LDState::ACTIVE: - { - CONTROLResumeEvent request; - request.cntlrName = controller->name; - controller->port->send(request); - } - break; - - case LDState::SUSPENDED: - { - CONTROLSuspendEvent request; - request.cntlrName = controller->name; - controller->port->send(request); - } - break; - - case LDState::RELEASED: - case LDState::FINISHED: - { - CONTROLReleaseEvent request; - request.cntlrName = controller->name; - controller->port->send(request); - } - break; - - default: - ASSERTSTR(false, "Unhandled action: " << action->requestedState); - } - action++; // hop to next - itsActionList.pop_front(); // remove handled action. - nrActions--; // one less to handle. - } - - if (itsActionList.size()) { // when unhandled actions in list - itsActionTimer = itsListener->setTimer(1.0); // restart timer - } - -} - -// -// _removeAction (controller, requestedState) -// -void ChildControl::_removeAction (const string& aName, - LDState::LDstateNr requestedState) -{ - CIiter iter = itsActionList.begin(); - const_CIiter end = itsActionList.end(); - - while (iter != end) { - if (iter->name == aName && iter->requestedState == requestedState) { - itsActionList.erase(iter); - return; - } - iter++; - } - - return; -} - -// -// _setEstablishedState (name, state, time) -// -void ChildControl::_setEstablishedState(const string& aName, - LDState::LDstateNr newState, - time_t atTime, - bool successful) -{ - CIiter controller = findController(aName); - if (controller == itsCntlrList.end()) { - LOG_WARN_STR ("Could not update state of controller " << aName); - return; - } - - // update controller information - if (!(controller->failed = !successful)) {; - controller->currentState = newState; - } - controller->establishTime = atTime; - - if (itsCompletionTimer) { - itsCompletionTimer->setTimer(0.0); - } - - if (!itsCompletionPort) { - return; - } - - LOG_DEBUG_STR("newState=" << newState); - - TLDResult result = controller->failed ? LD_RESULT_UNSPECIFIED : LD_RESULT_NO_ERROR; - switch (newState) { - case LDState::CREATED: { - CONTROLStartedEvent msg; - msg.cntlrName = controller->name; - msg.successful= successful; - itsCompletionPort->sendBack(msg); - } - break; - case LDState::CONNECTED: { - CONTROLConnectedEvent msg; - msg.cntlrName = controller->name; - msg.result = result; - itsCompletionPort->sendBack(msg); - } - break; - case LDState::CLAIMED: { - CONTROLClaimedEvent msg; - msg.cntlrName = controller->name; - msg.result = result; - itsCompletionPort->sendBack(msg); - } - break; - case LDState::PREPARED: { - CONTROLPreparedEvent msg; - msg.cntlrName = controller->name; - msg.result = result; - itsCompletionPort->sendBack(msg); - } - break; - case LDState::ACTIVE: { - CONTROLResumedEvent msg; - msg.cntlrName = controller->name; - msg.result = result; - itsCompletionPort->sendBack(msg); - } - break; - case LDState::SUSPENDED: { - CONTROLSuspendedEvent msg; - msg.cntlrName = controller->name; - msg.result = result; - itsCompletionPort->sendBack(msg); - } - break; - case LDState::RELEASED: { - CONTROLReleasedEvent msg; - msg.cntlrName = controller->name; - msg.result = result; - itsCompletionPort->sendBack(msg); - } - break; - case LDState::FINISHED: { - CONTROLFinishedEvent msg; - msg.cntlrName = controller->name; - msg.result = result; - itsCompletionPort->sendBack(msg); - } - break; - default: - // do nothing - break; - } -} - -// -------------------- STATE MACHINES FOR GCFTASK -------------------- - -// -// initial (event, port) -// -// Remember: there is nothing to do in the initial state until the user called -// 'openService' for our listener. After that service is called our task is to -// bring the listener alive. -// -GCFEvent::TResult ChildControl::initial (GCFEvent& event, - GCFPortInterface& port) -{ - LOG_DEBUG ("ChildControl::initial"); - - GCFEvent::TResult status = GCFEvent::HANDLED; - - switch (event.signal) { - case F_INIT: - break; - - case F_ENTRY: - break; - - case F_CONNECTED: - if (&port == itsListener) { - port.cancelAllTimers(); - LOG_DEBUG("Listener for children opened, going to operational state"); - TRAN (ChildControl::operational); - } - break; - - case F_DISCONNECTED: - port.close(); - if (&port == itsListener) { - port.setTimer(1.0); - } - else { -// _handleDisconnectEvent(event, port); - } - break; - - case F_TIMER: - // is this always the reconnect timer? - itsListener->open(); - break; - - default: - LOG_DEBUG ("ChildControl::initial, default"); - status = GCFEvent::NOT_HANDLED; - break; - } - - return (status); -} - -// -// operational (event, port) -// -// In the operational mode the users will request startup on new children (startChild) -// and state changes of existing children (requestState). -// -GCFEvent::TResult ChildControl::operational(GCFEvent& event, - GCFPortInterface& port) - -{ - LOG_DEBUG_STR ("ChildControl::operational:" << evtstr(event) - << "@" << port.getName()); - - GCFEvent::TResult status = GCFEvent::HANDLED; - - switch (event.signal) { - case F_INIT: - break; - - case F_ENTRY: - break; - - case F_ACCEPT_REQ: { - // Should be from a just started Child. - // accept connection and add port to port-vector - GCFTCPPort* client(new GCFTCPPort); - - // reminder: init (task, name, type, protocol [,raw]) - client->init(*this, "newChild", GCFPortInterface::SPP, - CONTROLLER_PROTOCOL); - itsListener->accept(*client); - - // Note: we do not keep an administration of the accepted child - // sockets. Their ports will be in the ControllerList as soon as - // they have send a CONNECTED msg. - } - break; - - case F_CONNECTED: - break; - - case F_DISCONNECTED: { - port.close(); // always close port - - CIiter controller = itsCntlrList.begin(); - CIiter end = itsCntlrList.end(); - while (controller != end) { - // search corresponding controller - if (controller->port != &port) { - controller++; - continue; - } - - // found controller, close port - if (controller->currentState == LDState::FINISHED) {// expected disconnect? - itsCntlrList.erase(controller); // just remove - } - else { - LOG_WARN_STR ("Lost connection with controller " << controller->name); - controller->port = 0; - // TODO: implement garbage collection - } - } - } - break; - - case F_TIMER: - itsActionTimer = 0; - _processActionList(); - break; - - case STARTDAEMON_CREATED: // startDaemon reports startup of program - { - STARTDAEMONCreatedEvent result(event); - LOG_DEBUG_STR("Startup of " << result.cntlrName << " ready, result=" - << result.result); - _setEstablishedState(result.cntlrName, LDState::CREATED, time(0), - result.result == SD_RESULT_NO_ERROR); - } - break; - - case CONTROL_CONNECT: // received from just started controller - { - CONTROLConnectEvent msg(event); - CONTROLConnectedEvent answer; - - CIiter controller = findController(msg.cntlrName); - if (controller == itsCntlrList.end()) { // not found? - LOG_WARN_STR ("CONNECT event received from unknown controller: " << - msg.cntlrName); - answer.result = LD_RESULT_UNSPECIFIED; - } - else { - LOG_DEBUG_STR("CONNECT event received from " << msg.cntlrName); - _setEstablishedState(msg.cntlrName, LDState::CONNECTED, time(0), true); - // first direct contact with controller, remember port - controller->port = &port; - answer.result = LD_RESULT_NO_ERROR; - } - port.send(answer); - } - break; - - case CONTROL_CLAIMED: - break; - - case CONTROL_PREPARED: - break; - - case CONTROL_RESUMED: - break; - - case CONTROL_SUSPENDED: - break; - - case CONTROL_RELEASED: - break; - - case CONTROL_FINISH: - break; - - - default: - LOG_DEBUG ("ChildControl::operational, default"); - status = GCFEvent::NOT_HANDLED; - break; - } - - return (status); -} - - } // namespace MainCU -} // namespace LOFAR diff --git a/MAC/APL/MainCU/src/MACScheduler/ChildControl.h b/MAC/APL/MainCU/src/MACScheduler/ChildControl.h deleted file mode 100644 index 332915cf399cc6740d04f51430deaf8fae041cb9..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ChildControl.h +++ /dev/null @@ -1,186 +0,0 @@ -//# ChildControl.h: GCFTask for managing child controllers -//# -//# Copyright (C) 2006 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ - -#ifndef MAINCU_CHILDCONTROL_H -#define MAINCU_CHILDCONTROL_H - -// \file -// GCFTask for managing child controllers - -//# Never #include <config.h> or #include <lofar_config.h> in a header file! -//# Includes -#include <Common/lofar_string.h> -#include <Common/lofar_map.h> -#include <Common/lofar_list.h> -#include <GCF/TM/GCF_Task.h> -#include <GCF/TM/GCF_ITCPort.h> -#include <GCF/TM/GCF_TCPPort.h> -#include <GCF/TM/GCF_TimerPort.h> -#include <APL/APLCommon/APL_Defines.h> -#include <OTDB/OTDBtypes.h> -#include "LDState.h" - -// Avoid 'using namespace' in headerfiles - -namespace LOFAR { - using GCF::TM::GCFTCPPort; - using GCF::TM::GCFEvent; - using GCF::TM::GCFTask; - using GCF::TM::GCFPortInterface; - using GCF::TM::GCFITCPort; - using GCF::TM::GCFTimerPort; - using APLCommon::LDState; - namespace MainCU { - -// \addtogroup MainCU -// @{ - -//# --- Forward Declarations --- -//# classes mentioned as parameter or returntype without virtual functions. -//class ...; - - -// class_description -// ... -class ChildControl : public GCFTask -{ -public: - // the only way to create the object is via instance. - static ChildControl* instance(); - ~ChildControl(); - - typedef struct StateInfo_t { - string name; // uniq name of controller - string cntlrType; // controller type mnemonic - bool isConnected; // is attached to task - LDState::LDstateNr requestedState; // state the controller should reach - time_t requestTime; // time of requested state - LDState::LDstateNr currentState; // currrent (known) state of the controller - time_t establishTime; // time this state was reached - bool failed; // the requested state could not be reached - } StateInfo; - - // Assign a name to the service the task should offer to the childs - void openService (const string& aServiceName, - uint32 instanceNr = 0); - - // Functions to manage the child controllers - bool startChild (const string& aName, - OTDB::treeIDType anObsID, - const string& aCntlrType, - uint32 instanceNr = 0, - const string& hostname = "localhost"); - bool requestState (LDState::LDstateNr state, - const string& aName, - OTDB::treeIDType anObsID = 0, - const string& aCntlrType = CNTLRTYPE_NO_TYPE); - uint32 countChilds (OTDB::treeIDType anObsID = 0, - const string& aCntlrType = CNTLRTYPE_NO_TYPE); - - LDState::LDstateNr getCurrentState (const string& aName); - LDState::LDstateNr getRequestedState (const string& aName); - - // management info for creator of class. - vector<StateInfo> getPendingRequest (const string& aName, - OTDB::treeIDType anObsID = 0, - const string& aCntlrType = CNTLRTYPE_NO_TYPE); - - // The 'parent' task that uses this ChildControl class has three way of getting - // informed about the completed actions: - // [A] call getCompletedStates at regular intervals. - // [B] call setCompletionTimer once and call getCompletedStates when timer expires - // [C] call setCompletionPort once and handle the CONTROL events on that port. - vector<StateInfo> getCompletedStates (time_t lastPollTime); - void registerCompletionTimer (GCFTimerPort* theTimerPort) - { itsCompletionTimer = theTimerPort; } - void registerCompletionPort (GCFITCPort* theITCPort) - { itsCompletionPort = theITCPort; } - -private: - // Copying is not allowed - ChildControl(); - ChildControl(const ChildControl& that); - ChildControl& operator=(const ChildControl& that); - - // GCFTask statemachines - GCFEvent::TResult initial (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult operational (GCFEvent& event, GCFPortInterface& port); - - // Internal routines - void _processActionList(); - void _setEstablishedState (const string& aName, - LDState::LDstateNr newState, - time_t atTime, - bool successful); - void _removeAction (const string& aName, - LDState::LDstateNr requestedState); - - // Define struct for administration of the child controllers. - typedef struct ControllerInfo_t { - string name; // uniq name of the controller - uint32 instanceNr; // for nonshared controllers - OTDB::treeIDType obsID; // observation tree the cntlr belongs to - GCFPortInterface* port; // connection with the controller - string cntlrType; // type of controller (mnemonic) - string hostname; // host the controller runs on - LDState::LDstateNr requestedState; // the state the controller should have - time_t requestTime; // time of requested state - LDState::LDstateNr currentState; // the state the controller has - time_t establishTime; // time the current state was reached - bool failed; // requested state could not be reached - time_t retryTime; // time the request must be retried - uint32 nrRetries; // nr of retries performed - } ControllerInfo; - typedef list<ControllerInfo>::iterator CIiter; - typedef list<ControllerInfo>::const_iterator const_CIiter; - CIiter findController(const string& name); - - //# --- Datamembers --- - GCFTCPPort* itsListener; // listener for child controllers - - map <string, GCFTCPPort*> itsStartDaemonMap; // map<hostname,sdconnection> - typedef map<string, GCFTCPPort*>::iterator SDiter; - typedef map<string, GCFTCPPort*>::const_iterator const_SDiter; - uint32 itsStartupRetryInterval; - uint32 itsMaxStartupRetries; - - list<ControllerInfo> itsCntlrList; // admin. of child controllers - - // All actions from the parent task are queued as ControllerInfo objects - // and handled in the operational stateMachine. - list<ControllerInfo> itsActionList; // list of actions to perform. - uint32 itsActionTimer; // ID of actiontimer. - - GCFTimerPort* itsCompletionTimer; // to signal parent in situation B - GCFITCPort* itsCompletionPort; // to signal parent in situation C -// ... - -}; - - -//# --- Inline functions --- - -// @} - } // namespace MainCU -} // namespace LOFAR - -#endif diff --git a/MAC/APL/MainCU/src/MACScheduler/LDState.cc b/MAC/APL/MainCU/src/MACScheduler/LDState.cc deleted file mode 100644 index 7eaad2b716fb22f8d36100b5984b738e2937cfb7..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/LDState.cc +++ /dev/null @@ -1,99 +0,0 @@ -//# LDState.cc: one_line_description -//# -//# Copyright (C) 2002-2004 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ - -//# Always #include <lofar_config.h> first! -#include <lofar_config.h> - -//# Includes -#include <Common/LofarLogger.h> -#include <LDState.h> - -namespace LOFAR { - namespace APLCommon { - -// -// LDState() -// -LDState::LDState() -{ - itsStates.resize(LAST_STATE); - itsStates[NOSTATE] = "Unknown"; - itsStates[CREATED] = "Created"; - itsStates[CONNECT] = "Connecting"; - itsStates[CONNECTED] = "Connected"; - itsStates[CLAIM] = "Claiming"; - itsStates[CLAIMED] = "Claimed"; - itsStates[PREPARE] = "Preparing"; - itsStates[PREPARED] = "Prepared"; - itsStates[ACTIVE] = "Active"; - itsStates[SUSPEND] = "Suspending"; - itsStates[SUSPENDED] = "Suspended"; - itsStates[RELEASE] = "Releasing"; - itsStates[RELEASED] = "Released"; - itsStates[FINISH] = "Finishing"; - itsStates[FINISHED] = "Finished"; -} - -// -// ~LDState() -// -LDState::~LDState() -{ -} - -// -// name(statenr) -// -string LDState::name(uint16 aStateNr) -{ - return ((aStateNr < LAST_STATE) ? itsStates[aStateNr] : ""); -} - -// -// value(name) -// -uint16 LDState::value(const string& aStateName) -{ - uint16 i = NOSTATE; - while (i < LAST_STATE) { - if (itsStates[i] == aStateName) { - return (i); - } - i++; - } - - ASSERTSTR(false, aStateName << " is not a valid LDState"); -} - -// -// value(LDstateNr) -// -uint16 LDState::value(LDstateNr aStateNr) -{ - ASSERTSTR((aStateNr >= NOSTATE) && (aStateNr < LAST_STATE), - aStateNr << " is not a valid LDState"); - - return ((uint16) aStateNr); -} - - } // namespace APL -} // namespace LOFAR diff --git a/MAC/APL/MainCU/src/MACScheduler/LDState.h b/MAC/APL/MainCU/src/MACScheduler/LDState.h deleted file mode 100644 index a32f85482373ff1049719819efc23534b2c42b0c..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/LDState.h +++ /dev/null @@ -1,105 +0,0 @@ -//# LDState.h: one_line_description -//# -//# Copyright (C) 2002-2004 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ - -#ifndef APL_LOGICALDEVICESTATE_H -#define APL_LOGICALDEVICESTATE_H - -// \file LDState.h -// one_line_description - -//# Never #include <config.h> or #include <lofar_config.h> in a header file! -//# Includes -#include <Common/lofar_map.h> - -// Avoid 'using namespace' in headerfiles - -namespace LOFAR { - namespace APLCommon { - -// \addtogroup package -// @{ - - -// class_description -// ... -class LDState -{ -public: - LDState(); - ~LDState(); - - // define enumeration for all states of an LogicalDevice. - typedef enum { - ANYSTATE = -1, - NOSTATE = 0, - CREATED, - CONNECT, - CONNECTED, - CLAIM, - CLAIMED, - PREPARE, - PREPARED, - ACTIVE, - SUSPEND, - SUSPENDED, - RELEASE, - RELEASED, - FINISH, - FINISHED, - LAST_STATE - } LDstateNr; - - // conversion routines - string name (uint16 aStateNr); - uint16 value(const string& aStateName); - uint16 value(LDstateNr aStateNr); - - // ... example - ostream& print (ostream& os) const - { return (os); } - -private: - // Copying is not allowed - LDState(const LDState& that); - LDState& operator=(const LDState& that); - - //# --- Datamembers --- - vector<string> itsStates; -}; - -//# --- Inline functions --- - -// ... example -//# -//# operator<< -//# -inline ostream& operator<< (ostream& os, const LDState& aLDState) -{ - return (aLDState.print(os)); -} - - -// @} - } // namespace APLCommon -} // namespace LOFAR - -#endif diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc index 5e155ac56f41a78427f839ee4ef7e486de9ec4dd..d0bd798fbb80ffd4bbc27771015d59772bac9c4c 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc @@ -26,9 +26,11 @@ #include <APS/ParameterSet.h> #include <GCF/GCF_ServiceInfo.h> #include <GCF/GCF_PVTypes.h> +#include <GCF/Protocols/PA_Protocol.ph> #include <GCF/PAL/GCF_PVSSInfo.h> #include <GCF/Utils.h> #include <APL/APLCommon/APL_Defines.h> +#include <APL/APLCommon/ControllerDefines.h> #include <APL/APLCommon/APLCommonExceptions.h> #include <APL/APLCommon/Controller_Protocol.ph> @@ -55,7 +57,7 @@ MACScheduler::MACScheduler() : itsPropertySetAnswer(*this), itsPropertySet (), // itsObsCntlrMap (), - itsDummyPort (0), + itsTimerPort (0), itsChildControl (0), itsChildPort (0), itsSecondTimer (0), @@ -78,6 +80,12 @@ MACScheduler::MACScheduler() : GCFPortInterface::SAP, CONTROLLER_PROTOCOL); ASSERTSTR(itsChildPort, "Cannot allocate ITCport for childcontrol"); itsChildPort->open(); // will result in F_CONNECTED + + // need port for timers + itsTimerPort = new GCFTimerPort(*this, "Timerport"); + + registerProtocol (CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_signalnames); + registerProtocol(PA_PROTOCOL, PA_PROTOCOL_signalnames); } @@ -90,7 +98,8 @@ MACScheduler::~MACScheduler() if (itsPropertySet) { itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("down")); - itsPropertySet->disable(); + // Note: disable is not neccesary because this is always done in destructor + // of propertyset. } if (itsOTDBconnection) { @@ -104,6 +113,9 @@ MACScheduler::~MACScheduler() // void MACScheduler::handlePropertySetAnswer(GCFEvent& answer) { + + LOG_DEBUG_STR ("handlePropertySetAnswer:" << evtstr(answer)); + switch(answer.signal) { case F_MYPS_ENABLED: { GCFPropSetAnswerEvent* pPropAnswer=static_cast<GCFPropSetAnswerEvent*>(&answer); @@ -111,6 +123,8 @@ void MACScheduler::handlePropertySetAnswer(GCFEvent& answer) LOG_ERROR(formatString("%s : PropertySet %s NOT ENABLED", getName().c_str(), pPropAnswer->pScope)); } + // always let timer expire so main task will continue. + itsTimerPort->setTimer(0.0); break; } @@ -166,7 +180,7 @@ void MACScheduler::handlePropertySetAnswer(GCFEvent& answer) // GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& /*port*/) { - LOG_DEBUG_STR ("MACScheduler::initial_state:" << evtstr(event)); + LOG_DEBUG_STR ("initial_state:" << evtstr(event)); GCFEvent::TResult status = GCFEvent::HANDLED; @@ -182,7 +196,11 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& PS_CAT_PERM_AUTOLOAD, &itsPropertySetAnswer)); itsPropertySet->enable(); + // Wait for timer that is set in PropertySetAnswer on ENABLED event. + } + break; + case F_TIMER: { // must be timer that PropSet is enabled. // update PVSS. LOG_TRACE_FLOW ("Updateing state to PVSS"); itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString ("initial")); @@ -212,8 +230,6 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& itsChildControl->openService(MAC_SVCMASK_SCHEDULERCTRL, 0); itsChildControl->registerCompletionPort(itsChildPort); - // need port for timers(!) - itsDummyPort = new GCFTimerPort(*this, "MACScheduler:dummy4timers"); TRAN(MACScheduler::recover_state); // go to next state. } break; @@ -224,9 +240,6 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& case F_DISCONNECTED: break; - case F_TIMER: - break; - default: LOG_DEBUG ("MACScheduler::initial, default"); status = GCFEvent::NOT_HANDLED; @@ -244,8 +257,7 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& // GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& port) { - LOG_DEBUG_STR ("MACScheduler::recover_state:" << evtstr(event) - << "@" << port.getName()); + LOG_DEBUG_STR ("recover_state:" << evtstr(event) << "@" << port.getName()); GCFEvent::TResult status = GCFEvent::HANDLED; @@ -267,7 +279,7 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& } default: - LOG_DEBUG("MACScheduler::recover_state, default"); + LOG_DEBUG("recover_state, default"); status = GCFEvent::NOT_HANDLED; break; } @@ -282,8 +294,7 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& // GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& port) { - LOG_DEBUG_STR ("MACScheduler::active:" << evtstr(event) - << "@" << port.getName()); + LOG_DEBUG_STR ("active:" << evtstr(event) << "@" << port.getName()); GCFEvent::TResult status = GCFEvent::HANDLED; @@ -297,7 +308,7 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); // Timers must be connected to ports, so abuse serverPort for second timer. - itsSecondTimer = itsDummyPort->setTimer(1L); + itsSecondTimer = itsTimerPort->setTimer(1L); break; } @@ -345,7 +356,7 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& } else { LOG_ERROR_STR("Observation controller " << msg.cntlrName << - " could n ot be started"); + " could not be started"); } // TODO: do something usefull with this information! break; @@ -405,13 +416,14 @@ void MACScheduler::_doOTDBcheck() } // get current state of Observation - string cntlrName = formatString("Observation_%d", newTreeList[idx].treeID()); - LDState::LDstateNr observationState = itsChildControl->getRequestedState(cntlrName); + string cntlrName = controllerName(CNTLRTYPE_OBSERVATIONCTRL, + 0, newTreeList[idx].treeID()); + CTState::CTstateNr observationState = itsChildControl->getRequestedState(cntlrName); // remember: timediff <= queueperiod if (timediff > seconds(itsClaimPeriod)) { // Observation is somewhere in the queueperiod - if (observationState != LDState::CONNECTED) { // requested a start before? + if (observationState != CTState::CONNECTED) { // requested a start before? // no, let database construct the parset for the whole observation OTDB::TreeMaintenance tm(itsOTDBconnection); OTDB::treeIDType treeID = newTreeList[idx].treeID(); @@ -437,7 +449,7 @@ void MACScheduler::_doOTDBcheck() if (timediff > seconds(0)) { // Observation is somewhere in the claim period - if (observationState != LDState::CLAIMED) { + if (observationState != CTState::CLAIMED) { // _claimObservation(&newTreeList[idx]); idx++; continue; @@ -445,7 +457,7 @@ void MACScheduler::_doOTDBcheck() } // observation must be running (otherwise it would not be in the newTreeList) - if (observationState != LDState::ACTIVE) { + if (observationState != CTState::ACTIVE) { // _executeObservation(&newTreeList[idx]); } diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h index e313c12d5608f6a10f0635def61e9544572eb2ef..0561ebd39abdcb351ba29e3f68e35df312232734 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h @@ -35,10 +35,12 @@ #include <GCF/TM/GCF_Event.h> //# local includes -#include "APL/APLCommon/PropertySetAnswerHandlerInterface.h" -#include "APL/APLCommon/PropertySetAnswer.h" -#include "APL/APLCommon/APLCommonExceptions.h" -#include "APL/APLCommon/Controller_Protocol.ph" +#include <APL/APLCommon/PropertySetAnswerHandlerInterface.h> +#include <APL/APLCommon/PropertySetAnswer.h> +#include <APL/APLCommon/APLCommonExceptions.h> +#include <APL/APLCommon/Controller_Protocol.ph> +#include <APL/APLCommon/ChildControl.h> +#include <APL/APLCommon/CTState.h> //# Common Includes #include <Common/lofar_string.h> @@ -50,8 +52,6 @@ #include <OTDB/TreeMaintenance.h> #include <OTDB/OTDBnode.h> #include <APS/ParameterSet.h> -#include "ChildControl.h" -#include "LDState.h" // forward declaration @@ -119,7 +119,7 @@ private: #endif // Ports for StartDaemon and ObservationControllers. - GCFTimerPort* itsDummyPort; // for timers + GCFTimerPort* itsTimerPort; // for timers // pointer to child control task ChildControl* itsChildControl; diff --git a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h index 397840acb7d23e196ec006d626435b19b6c4c46f..23ad12832fc4fead7b6a6c91ef74be09f8f53fa5 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h +++ b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h @@ -32,7 +32,7 @@ namespace LOFAR { #define MS_PROPSET_TYPE "MacScheduler" #define MS_OTDB_CONNECTED "OTDB.connected" #define MS_OTDB_LASTPOLL "OTDB.lastPoll" -#define MS_OTDB_POLL_ITV "OTDB.pollInterval" +#define MS_OTDB_POLL_ITV "OTDB.pollinterval" #define PVSSNAME_MS_QUEUEPERIOD "QueuePeriod" #define PVSSNAME_MS_CLAIMPERIOD "ClaimPeriod" diff --git a/MAC/APL/MainCU/src/MACScheduler/Makefile.am b/MAC/APL/MainCU/src/MACScheduler/Makefile.am index 21d2cca60b487f065164ca11bf331f57520ad584..9af99a6f4da3a78a20313b2ecd468dfee7d0046f 100644 --- a/MAC/APL/MainCU/src/MACScheduler/Makefile.am +++ b/MAC/APL/MainCU/src/MACScheduler/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS = MACScheduler ObservationControl +bin_PROGRAMS = MACScheduler MACScheduler_CPPFLAGS = -DBOOST_DISABLE_THREADS \ -Wno-deprecated \ @@ -6,34 +6,15 @@ MACScheduler_CPPFLAGS = -DBOOST_DISABLE_THREADS \ -fdiagnostics-show-location=once MACScheduler_SOURCES = MACScheduler.cc \ - MACSchedulerMain.cc \ - ChildControl.cc \ - LDState.cc - ParentControl.cc + MACSchedulerMain.cc MACScheduler_LDADD = -lpqxx $(LOFAR_DEPEND) MACScheduler_DEPENDENCIES = $(LOFAR_DEPEND) -ObservationControl_CPPFLAGS = -DBOOST_DISABLE_THREADS \ - -Wno-deprecated \ - -fmessage-length=0 \ - -fdiagnostics-show-location=once - -ObservationControl_SOURCES = ObservationControl.cc \ - ObservationControlMain.cc \ - ChildControl.cc \ - LDState.cc\ - ParentControl.cc - -ObservationControl_LDADD = $(LOFAR_DEPEND) -ObservationControl_DEPENDENCIES = $(LOFAR_DEPEND) - NOINSTHDRS = MACScheduler.h \ MACSchedulerDefines.h -INSTHDRS = ChildControl.h \ - ParentControl.h \ - LDState.h +INSTHDRS = pkginclude_HEADERS = $(NOINSTHDRS) $(INSTHDRS) @@ -46,9 +27,7 @@ configfilesdir=$(bindir) configfiles_DATA = customPrepPVSSDB.ctl sysconf_DATA = MACScheduler.conf \ - MACScheduler.log_prop \ - ObservationControl.conf \ - ObservationControl.log_prop + MACScheduler.log_prop %.log_prop: %.log_prop.in cp $< $@ diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.cc b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.cc deleted file mode 100644 index 4831f8772e6d515d208d7912c5be28e31a32bcbf..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.cc +++ /dev/null @@ -1,357 +0,0 @@ -//# ObservationControl.cc: Implementation of the MAC Scheduler task -//# -//# Copyright (C) 2002-2004 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ -#include <lofar_config.h> -#include <Common/LofarLogger.h> - -#include <boost/shared_array.hpp> -#include <APS/ParameterSet.h> -#include <GCF/GCF_PVTypes.h> -#include <GCF/PAL/GCF_PVSSInfo.h> -#include <GCF/Utils.h> -#include <GCF/GCF_ServiceInfo.h> -#include <APL/APLCommon/APL_Defines.h> -#include <APL/APLCommon/APLCommonExceptions.h> -#include <APL/APLCommon/Controller_Protocol.ph> - -#include "ObservationControl.h" -#include "MACSchedulerDefines.h" - -using namespace LOFAR::GCF::Common; -using namespace LOFAR::GCF::TM; -using namespace LOFAR::GCF::PAL; -using namespace LOFAR::OTDB; -using namespace std; - -namespace LOFAR { - using namespace APLCommon; - using namespace ACC::APS; - namespace MainCU { - -// -// ObservationControl() -// -ObservationControl::ObservationControl(const string& cntlrName) : - GCFTask ((State)&ObservationControl::initial_state,cntlrName), - PropertySetAnswerHandlerInterface(), - itsPropertySetAnswer(*this), - itsPropertySet (), - itsChildControl (0), - itsChildPort (0), - itsParentControl (0), - itsParentPort (0) -{ - LOG_TRACE_OBJ_STR (cntlrName << " construction"); - - // Readin some parameters from the ParameterSet. - itsTreePrefix = globalParameterSet()->getString("prefix"); - itsInstanceNr = globalParameterSet()->getUint32(itsTreePrefix + ".instanceNr"); - itsStartTime = globalParameterSet()->getTime (itsTreePrefix + ".starttime"); - itsStopTime = globalParameterSet()->getTime (itsTreePrefix + ".stoptime"); - - // attach to child control task - itsChildControl = ChildControl::instance(); - itsChildPort = new GCFITCPort (*this, *itsChildControl, "childITCport", - GCFPortInterface::SAP, CONTROLLER_PROTOCOL); - ASSERTSTR(itsChildPort, "Cannot allocate ITCport for childcontrol"); - itsChildPort->open(); // will result in F_CONNECTED - - // attach to parent control task - itsParentControl = ParentControl::instance(); - itsParentPort = new GCFITCPort (*this, *itsParentControl, "ParentITCport", - GCFPortInterface::SAP, CONTROLLER_PROTOCOL); - ASSERTSTR(itsChildPort, "Cannot allocate ITCport for Parentcontrol"); - itsParentPort->open(); // will result in F_CONNECTED -} - - -// -// ~ObservationControl() -// -ObservationControl::~ObservationControl() -{ - LOG_TRACE_OBJ_STR (getName() << " destruction"); - - if (itsPropertySet) { - itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("down")); - itsPropertySet->disable(); - } - - // ... -} - - -// -// handlePropertySetAnswer(answer) -// -void ObservationControl::handlePropertySetAnswer(GCFEvent& answer) -{ - switch(answer.signal) { - case F_MYPS_ENABLED: { - GCFPropSetAnswerEvent* pPropAnswer=static_cast<GCFPropSetAnswerEvent*>(&answer); - if(pPropAnswer->result != GCF_NO_ERROR) { - LOG_ERROR(formatString("%s : PropertySet %s NOT ENABLED", - getName().c_str(), pPropAnswer->pScope)); - } - break; - } - - case F_PS_CONFIGURED: - { - GCFConfAnswerEvent* pConfAnswer=static_cast<GCFConfAnswerEvent*>(&answer); - if(pConfAnswer->result == GCF_NO_ERROR) { - LOG_DEBUG(formatString("%s : apc %s Loaded", - getName().c_str(), pConfAnswer->pApcName)); - //apcLoaded(); - } - else { - LOG_ERROR(formatString("%s : apc %s NOT LOADED", - getName().c_str(), pConfAnswer->pApcName)); - } - break; - } - - case F_VGETRESP: - case F_VCHANGEMSG: { - // check which property changed - GCFPropValueEvent* pPropAnswer=static_cast<GCFPropValueEvent*>(&answer); - - // TODO: implement something usefull. - // change of queueTime - if ((strstr(pPropAnswer->pPropName, MS_PROPSET_NAME) != 0) && - (pPropAnswer->pValue->getType() == LPT_INTEGER)) { - uint32 newVal = (uint32) ((GCFPVInteger*)pPropAnswer->pValue)->getValue(); -#if 0 - if (strstr(pPropAnswer->pPropName, PVSSNAME_MS_QUEUEPERIOD) != 0) { - LOG_INFO_STR ("Changing QueuePeriod from " << itsQueuePeriod << - " to " << newVal); - itsQueuePeriod = newVal; - } - else if (strstr(pPropAnswer->pPropName, PVSSNAME_MS_CLAIMPERIOD) != 0) { - LOG_INFO_STR ("Changing ClaimPeriod from " << itsClaimPeriod << - " to " << newVal); - itsClaimPeriod = newVal; - } -#endif - } - break; - } - - default: - break; - } -} - - -// -// initial_state(event, port) -// -// Setup all connections. -// -GCFEvent::TResult ObservationControl::initial_state(GCFEvent& event, GCFPortInterface& /*port*/) -{ - LOG_DEBUG_STR ("ObservationControl::initial:" << evtstr(event)); - - GCFEvent::TResult status = GCFEvent::HANDLED; - - switch (event.signal) { - case F_INIT: - break; - - case F_ENTRY: { - // Get access to my own propertyset. - LOG_DEBUG ("Activating PropertySet"); - string propSetName = formatString(OC_PROPSET_NAME, itsInstanceNr); - itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(propSetName.c_str(), - OC_PROPSET_TYPE, - PS_CAT_TEMPORARY, - &itsPropertySetAnswer)); - itsPropertySet->enable(); - - // update PVSS. - LOG_TRACE_FLOW ("Updateing state to PVSS"); - itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString ("initial")); - itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString ("")); - - // Start ChildControl task - LOG_DEBUG ("Enabling ChildControl task"); - itsChildControl->openService(MAC_SVCMASK_OBSERVATIONCTRL, itsInstanceNr); - itsChildControl->registerCompletionPort(itsChildPort); - - // Start ParentControl task - LOG_DEBUG ("Enabling ParentControl task"); - itsParentPort = itsParentControl->registerTask(this); - - TRAN(ObservationControl::active_state); // go to next state. - } - break; - - case F_CONNECTED: - break; - - case F_DISCONNECTED: - break; - - case F_TIMER: - break; - - default: - LOG_DEBUG_STR ("ObservationControl::initial, default"); - status = GCFEvent::NOT_HANDLED; - break; - } - return (status); -} - - -// -// active_state(event, port) -// -// Normal operation state. -// -GCFEvent::TResult ObservationControl::active_state(GCFEvent& event, GCFPortInterface& port) -{ - LOG_DEBUG_STR ("ObservationControl::active:" << evtstr(event) - << "@" << port.getName()); - - GCFEvent::TResult status = GCFEvent::HANDLED; - - switch (event.signal) { - case F_INIT: - break; - - case F_ENTRY: { - // update PVSS - itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active")); - itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); - break; - } - - case F_ACCEPT_REQ: - break; - - case F_CONNECTED: - _connectedHandler(port); - break; - - case F_DISCONNECTED: - _disconnectedHandler(port); - break; - - case F_TIMER: -// GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); - break; - - // -------------------- EVENT RECEIVED FROM CHILD CONTROL -------------------- - case CONTROL_STARTED: { - CONTROLStartedEvent msg(event); - LOG_DEBUG(formatString("Start of %s was %ssuccessful", msg.cntlrName.c_str(), - msg.successful ? "" : "NOT ")); - // TODO: do something usefull with this information! - break; - } - - case CONTROL_CONNECT: { - CONTROLConnectEvent msg(event); - LOG_DEBUG_STR("Received CONNECT(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! - break; - } - - case CONTROL_SCHEDULED: { - CONTROLScheduledEvent msg(event); - LOG_DEBUG_STR("Received SCHEDULED(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! - break; - } - - case CONTROL_CLAIMED: { - CONTROLClaimedEvent msg(event); - LOG_DEBUG_STR("Received CLAIMED(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! - break; - } - - case CONTROL_PREPARED: { - CONTROLPreparedEvent msg(event); - LOG_DEBUG_STR("Received PREPARED(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! - break; - } - - case CONTROL_RESUMED: { - CONTROLResumedEvent msg(event); - LOG_DEBUG_STR("Received RESUMED(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! - break; - } - - case CONTROL_SUSPENDED: { - CONTROLSuspendedEvent msg(event); - LOG_DEBUG_STR("Received SUSPENDED(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! - break; - } - - case CONTROL_RELEASED: { - CONTROLReleasedEvent msg(event); - LOG_DEBUG_STR("Received RELEASED(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! - break; - } - - case CONTROL_FINISH: { - CONTROLFinishEvent msg(event); - LOG_DEBUG_STR("Received FINISH(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! - break; - } - - - default: - LOG_DEBUG(formatString("ObservationControl(%s)::active_state, default", - getName().c_str())); - status = GCFEvent::NOT_HANDLED; - break; - } - - return (status); -} - - -// -// _connectedHandler(port) -// -void ObservationControl::_connectedHandler(GCFPortInterface& port) -{ -} - -// -// _disconnectedHandler(port) -// -void ObservationControl::_disconnectedHandler(GCFPortInterface& port) -{ - port.close(); -} - - -}; -}; diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.conf.in b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.conf.in deleted file mode 100644 index a92957c18ce62d80f87bec0b8500f109d6a9d311..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.conf.in +++ /dev/null @@ -1,11 +0,0 @@ -# new setup -prefix = Observation0 - -Observation0.instanceNr = 0 -Observation0.starttime = 0 -Observation0.stoptime = 1 - -# next parameters are optional, defaultvalues are shown -#ChildControl.StartupRetryInterval = 10s -#ChildControl.MaxStartupRetry = 5 - diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.h b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.h deleted file mode 100644 index 6169b8cd624ecaf55637bcd8baf96d998f1a48b9..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.h +++ /dev/null @@ -1,131 +0,0 @@ -//# ObservationControl.h: Interface between MAC and SAS. -//# -//# Copyright (C) 2002-2004 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ - -#ifndef ObservationControl_H -#define ObservationControl_H - -//# Includes -#include <boost/shared_ptr.hpp> - -//# GCF Includes -#include <GCF/PAL/GCF_MyPropertySet.h> -#include <GCF/TM/GCF_Port.h> -#include <GCF/TM/GCF_ITCPort.h> -#include <GCF/TM/GCF_TimerPort.h> -#include <GCF/TM/GCF_Task.h> -#include <GCF/TM/GCF_Event.h> - -//# local includes -#include "APL/APLCommon/PropertySetAnswerHandlerInterface.h" -#include "APL/APLCommon/PropertySetAnswer.h" -#include "APL/APLCommon/APLCommonExceptions.h" -#include "APL/APLCommon/Controller_Protocol.ph" - -//# Common Includes -#include <Common/lofar_string.h> -#include <Common/lofar_vector.h> -#include <Common/LofarLogger.h> - -//# ACC Includes -#include <APS/ParameterSet.h> -#include "ChildControl.h" -#include "ParentControl.h" -#include "LDState.h" - -// forward declaration - -namespace LOFAR { - namespace MainCU { - -using GCF::TM::GCFTimerPort; -using GCF::TM::GCFITCPort; -using GCF::TM::GCFPort; -using GCF::TM::GCFEvent; -using GCF::TM::GCFPortInterface; -using GCF::TM::GCFTask; - - -class ObservationControl : public GCFTask, - APLCommon::PropertySetAnswerHandlerInterface -{ -public: - explicit ObservationControl(const string& cntlrName); - ~ObservationControl(); - - // PropertySetAnswerHandlerInterface method - virtual void handlePropertySetAnswer(GCFEvent& answer); - - // During the initial state all connections with the other programs are made. - GCFEvent::TResult initial_state (GCFEvent& e, - GCFPortInterface& p); - - // Normal control mode. - GCFEvent::TResult active_state (GCFEvent& e, - GCFPortInterface& p); - -private: - // avoid defaultconstruction and copying - ObservationControl(); - ObservationControl(const ObservationControl&); - ObservationControl& operator=(const ObservationControl&); - - void _connectedHandler(GCFPortInterface& port); - void _disconnectedHandler(GCFPortInterface& port); - boost::shared_ptr<ACC::APS::ParameterSet> - readObservationParameters (OTDB::treeIDType ObsTreeID); - - typedef boost::shared_ptr<GCF::PAL::GCFMyPropertySet> GCFMyPropertySetPtr; - - APLCommon::PropertySetAnswer itsPropertySetAnswer; - GCFMyPropertySetPtr itsPropertySet; - -#if 0 - // Administration of the ObservationControllers - typedef struct { - OTDB::treeIDType treeID; // tree in the OTDB - GCFTCPPort* port; // TCP connection with controller - uint16 state; // state the controller has - } ObsCntlr_t; - - // Map with all active ObservationControllers. - map<GCFTCPPort*, ObsCntlr_t> itsObsCntlrMap; - vector<GCFTCPPort*> itsObsCntlrPorts; -#endif - - // pointer to child control task - ChildControl* itsChildControl; - GCFITCPort* itsChildPort; - - // pointer to parent control task - ParentControl* itsParentControl; - GCFITCPort* itsParentPort; - - // ParameterSet variables - string itsTreePrefix; - uint32 itsInstanceNr; - time_t itsStartTime; - time_t itsStopTime; -}; - - };//MainCU -};//LOFAR -#endif diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.log_prop.in b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.log_prop.in deleted file mode 100644 index 014e32162d939ee0cd2716348fc1e2e9117c10ad..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.log_prop.in +++ /dev/null @@ -1,20 +0,0 @@ -# add your custom loggers and appenders here -# - -log4cplus.rootLogger=DEBUG, STDOUT, FILE - -log4cplus.logger.TRC=TRACE2 -log4cplus.additivity.TRC=FALSE - -log4cplus.appender.STDOUT=log4cplus::ConsoleAppender -log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout -log4cplus.appender.STDOUT.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{9} - %m [%.25l]%n -log4cplus.appender.STDOUT.logToStdErr=true - -log4cplus.appender.FILE=log4cplus::RollingFileAppender -log4cplus.appender.FILE.File=../log/ObservationControl.log -log4cplus.appender.FILE.MaxFileSize=5MB -log4cplus.appender.FILE.MaxBackupIndex=5 -log4cplus.appender.FILE.layout=log4cplus::PatternLayout -log4cplus.appender.FILE.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%.25l]%n - diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControlMain.cc b/MAC/APL/MainCU/src/MACScheduler/ObservationControlMain.cc deleted file mode 100644 index 085868055868317950b9ed1314587ae9e46717eb..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ObservationControlMain.cc +++ /dev/null @@ -1,49 +0,0 @@ -//# ObservationControlMain.cc: Main entry for the ObservationControl controller. -//# -//# Copyright (C) 2006 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ -//# -#include <lofar_config.h> -#include <Common/LofarLogger.h> - -#include "ObservationControl.h" - -using namespace LOFAR::GCF::TM; -using namespace LOFAR::MainCU; - -int main(int argc, char* argv[]) -{ - // args: cntlrname, parentHost, parentService - GCFTask::init(argc, argv); - - ChildControl* cc = ChildControl::instance(); - cc->start(); // make initial transition - - ParentControl* pc = ParentControl::instance(); - pc->start(); // make initial transition - - ObservationControl oc(argv[1]); - oc.start(); // make initial transition - - GCFTask::run(); - - return 0; -} - diff --git a/MAC/APL/MainCU/src/MACScheduler/ParentControl.cc b/MAC/APL/MainCU/src/MACScheduler/ParentControl.cc deleted file mode 100644 index 7dc67f2a7c6721d7ef82304fbdf86e62ec5db172..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ParentControl.cc +++ /dev/null @@ -1,572 +0,0 @@ -//# ParentControl.cc: Task that handles and dispatches all controllers events. -//# -//# Copyright (C) 2006 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ - -//# Always #include <lofar_config.h> first! -#include <lofar_config.h> - -//# Includes -#include <Common/LofarLogger.h> -#include <APS/ParameterSet.h> -#include <MainCU/MACScheduler/ParentControl.h> -#include <GCF/GCF_ServiceInfo.h> -#include <GCF/Utils.h> -#include <APL/APLCommon/APLUtilities.h> -#include <APL/APLCommon/Controller_Protocol.ph> -#include <APL/APLCommon/StartDaemon_Protocol.ph> -#include "ParentControl.h" - -namespace LOFAR { - using namespace GCF::TM; - using namespace APLCommon; - using namespace ACC::APS; - namespace MainCU { - -typedef struct stateFlow_t { - uint16 signal; - LDState::LDstateNr currentState; - LDState::LDstateNr requestedState; -} stateFlow; - -static stateFlow stateFlowTable[] = { -// received signal expected in state requested state -// ------------------------------------------------------------------ - { CONTROL_CONNECTED, LDState::CONNECT, LDState::CONNECTED }, - { CONTROL_CLAIM, LDState::CONNECTED, LDState::CLAIMED }, - { CONTROL_PREPARE, LDState::CLAIMED, LDState::PREPARED }, - { CONTROL_RESUME, LDState::PREPARED, LDState::ACTIVE }, - { CONTROL_RESUME, LDState::SUSPENDED, LDState::ACTIVE }, - { CONTROL_SUSPEND, LDState::ACTIVE, LDState::SUSPENDED }, - { CONTROL_RELEASE, LDState::ANYSTATE, LDState::RELEASED }, - { CONTROL_FINISHED, LDState::FINISH, LDState::FINISHED }, - { 0x00, LDState::NOSTATE, LDState::NOSTATE } -}; - -//-------------------------- creation and destroy --------------------------- - -ParentControl* ParentControl::instance() -{ - static ParentControl* theirParentControl; - - if (theirParentControl == 0) { - theirParentControl = new ParentControl(); - } - return (theirParentControl); -} - - -// -// ParentControl(name, porenthost, parentService)) -// -ParentControl::ParentControl() : - GCFTask ((State)&ParentControl::initial, "ParentControl"), - itsParentList (), - itsSDPort (0), - itsMainTaskPort (0), - itsTimerPort (*this, "parentControlTimer"), - itsControllerName() -{ - // Log the protocols I use. - registerProtocol(CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_signalnames); - registerProtocol(STARTDAEMON_PROTOCOL, STARTDAEMON_PROTOCOL_signalnames); - -} - -// -// ~ParentControl -// -ParentControl::~ParentControl() -{ - // close and delete the ports I created - if (itsMainTaskPort) { - itsMainTaskPort->close(); - delete itsMainTaskPort; - } - - if (itsSDPort) { - itsSDPort->close(); - delete itsSDPort; - } -} - -// -// registerTask(mainTask) : ITCPort -// -GCFITCPort* ParentControl::registerTask(GCFTask* mainTask) -{ - itsMainTaskPort = new GCFITCPort(*mainTask, *this, mainTask->getName(), - GCFPortInterface::SAP, CONTROLLER_PROTOCOL); - ASSERTSTR(itsMainTaskPort, "Can not allocate ITC port for parent-control"); - itsMainTaskPort->open(); // will result in F_CONN signal - - itsSDPort = new GCFTCPPort(*this, MAC_SVCMASK_STARTDAEMON, - GCFPortInterface::SAP, STARTDAEMON_PROTOCOL); - ASSERTSTR(itsSDPort, "Can not allocate clientport to startDaemon"); - itsSDPort->open(); // will result in F_COON or F_DISCONN signal - - itsControllerName = mainTask->getName(); // remember for later - - return (itsMainTaskPort); -} - -// -// isLegalSignal(signal, parent) -// -bool ParentControl::isLegalSignal(uint16 aSignal, - PIiter aParent) -{ - uint32 i = 0; - while (stateFlowTable[i].signal) { - if (stateFlowTable[i].signal == aSignal && - (stateFlowTable[i].currentState == aParent->currentState || - stateFlowTable[i].currentState == LDState::ANYSTATE)) { - return (true); - } - i++; - } - return (false); -} - -// -// requestedState(signal) -// -LDState::LDstateNr ParentControl::requestedState(uint16 aSignal) -{ - uint32 i = 0; - while (stateFlowTable[i].signal) { - if (stateFlowTable[i].signal == aSignal) { - return (stateFlowTable[i].requestedState); - } - i++; - } - ASSERTSTR(false, "No new state defined for signal " << evtstr(aSignal)); -} - -// -// doRequestedAction(parent) -// -void ParentControl::doRequestedAction(PIiter parent) -{ - LOG_TRACE_FLOW_STR("doRequestedAction:" << parent->name); - - // state alredy reached? make sure the timer is off. - if (parent->requestedState == parent->currentState) { - parent->nrRetries = -1; - itsTimerPort.cancelTimer(parent->timerID); - parent->timerID = 0; - return; - } - - switch (parent->requestedState) { - case LDState::CONNECTED: { - // try to make first contact with parent by identifying ourself - if (parent->nrRetries == 0) { // no more retries left? - LOG_ERROR_STR("Cannot connect to parent: " << parent->servicename << - "@" << parent->hostname << ", giving up!"); - parent->establishTime = time(0); - parent->failed = true; // TODO:let garbage collection remove this entry. - return; - } - // Note: when required state == CONNECTED there are two possibilities: - // current state == NOSTATE: CONNECT msg was sent to main task, do nothing - // current state == CONNECT: CONNECTED msg was received from main task, - // send CONNECT msg to parent-controller. - if (parent->currentState == LDState::NOSTATE) { - return; - } - - ASSERTSTR(parent->currentState == LDState::CONNECT, - "Unexpected state:" << parent->currentState); - - // construct and send message - CONTROLConnectEvent hello; - hello.cntlrName = parent->name; - parent->port->send(hello); - parent->timerID = 0; - parent->nrRetries = -1; - parent->currentState = LDState::CONNECT; - parent->establishTime = time(0); - } - break; - case LDState::CLAIMED: { - CONTROLClaimEvent request; - request.cntlrName = parent->name; - itsMainTaskPort->sendBack(request); - } - break; - case LDState::PREPARED: -// concrete_prepare(parent); - break; - case LDState::ACTIVE: -// concrete_resume(parent); - break; - case LDState::SUSPENDED: -// concrete_suspend(parent); - break; - case LDState::RELEASED: -// concrete_release(parent); - break; - case LDState::FINISHED: - parent->port->close(); - itsParentList.erase(parent); - break; - default: - ASSERTSTR(false, "Serious programming error, requestedState=" << - parent->requestedState << " for task " << parent->name); - } - -} - - -// -------------------- THE GCF STATEMACHINES -------------------- - -// Wait for the F_CONNECTED event from the ITC port with the master-task. -// Connect and register at startDaemon -// -GCFEvent::TResult ParentControl::initial(GCFEvent& event, - GCFPortInterface& port) - -{ - LOG_DEBUG_STR ("ParentControl::initial:" << evtstr(event) - << "@" << port.getName()); - - GCFEvent::TResult status = GCFEvent::HANDLED; - - switch (event.signal) { - case F_INIT: - case F_ENTRY: - break; - - case F_CONNECTED: - if (&port == itsMainTaskPort) { // ITC port with parent open? - LOG_DEBUG("Connection with maintask opened"); - } - if (&port == itsSDPort) { - STARTDAEMONAnnouncementEvent msg; - msg.cntlrName = itsControllerName; - itsSDPort->send(msg); - - LOG_DEBUG_STR("Registered at startdaemon as " << itsControllerName - << ", going to operation mode"); - TRAN(ParentControl::operational); - } - break; - - case F_DISCONNECTED: - if (&port == itsSDPort) { - port.close(); - itsTimerPort.setTimer(1.0); - LOG_DEBUG("Could not connect to startDaemon, retry in 1 second"); - } - break; - - case F_TIMER: - // must be reconnect timer for startDaemon - itsSDPort->open(); - break; - - default: - LOG_DEBUG ("ParentControl::initial, default"); - status = GCFEvent::NOT_HANDLED; - break; - } - - return (status); -} - - -// -// operational (event, port) -// -// Since this base class is also used for shared controllers the controller supports -// multiple parents. For each of these parents the controller plays the role of -// stand-alone controller having a certain state and allowing certain actions. -// It is therefor difficult to implement multiple statemachine since the controller -// should be in a (different) state for each parent. -// -GCFEvent::TResult ParentControl::operational(GCFEvent& event, - GCFPortInterface& port) - -{ - LOG_DEBUG_STR ("ParentControl::operational:" << evtstr(event) - << "@" << port.getName()); - - GCFEvent::TResult status = GCFEvent::HANDLED; - - switch (event.signal) { - case F_INIT: - break; - - case F_ENTRY: - break; - - case F_ACCEPT_REQ: // will not occur, using SPP port for startDaemon - break; - - case F_CONNECTED: { - // search which connection is succesfull connected. - PIiter parent = findParent(&port); - if (isParent(parent)) { - // TODO: should we send an 'alive' msg to our parent - // so that recovered(?) parent knows we are still running? - // CHECK: is servicemask resolved at each open()? - - // contact with parent is (re)made - doRequestedAction(parent); - } - else { - LOG_DEBUG("F_CONNECTED on non-parent port"); - } - } - break; - - case F_DISCONNECTED: { - // StartDaemonPort? no problem SD will reconnect when neccesary. - if (&port == itsSDPort) { - port.close(); // close connection with current SD - port.open(); // start listener again - break; - } - - // Parent port? Might be temporarely problem, try to reconnect for a while. - PIiter parent = findParent(&port); - if (isParent(parent)) { - // trying to make first contact? - if (parent->requestedState == LDState::CONNECTED && - parent->currentState != LDState::CONNECTED) { - // try again in one second. - parent->port->close(); - parent->timerID = itsTimerPort.setTimer(1.0); - if (parent->nrRetries < 0) { - parent->nrRetries = 30; - LOG_WARN_STR ("Lost connection with new parent " << parent->name << - ", starting reconnect sequence"); - } - LOG_TRACE_VAR_STR("parent:" << parent->name << ", timerID:" - << parent->timerID); - break; - } - - // lost connection during normal operation, start reconnect sequence - parent->port->close(); - parent->timerID = itsTimerPort.setTimer(10.0);// retry every 10 seconds - if (parent->nrRetries < 0) { - parent->nrRetries = 360; // for 1 hour - LOG_WARN_STR ("Lost connection with parent " << parent->name << - ", starting reconnect sequence"); - } - LOG_TRACE_VAR_STR("parent:" << parent->name << ", timerID:" - << parent->timerID); - break; - } - - // unknown port. just close it. - LOG_INFO ("Lost connection with unknown port, closing it"); - port.close(); - } - break; - - case F_TIMER: { - GCFTimerEvent& timerEvent = static_cast<GCFTimerEvent&>(event); - LOG_TRACE_VAR_STR("timerID:" << timerEvent.id); - PIiter parent = findParent(timerEvent.id); - if (!isParent(parent)) { - LOG_DEBUG ("timerevent is not of a known parent, ignore"); - break; - } - - if (parent->port->isConnected()) { // not the reconnect timer? - doRequestedAction(parent); - } - - // its the reconnect timer of this parent. - if (parent->nrRetries > 0) { - parent->port->open(); - parent->nrRetries--; - parent->timerID = 0; - if (!parent->nrRetries%60) { - LOG_WARN_STR ("Still no connection with parent " << parent->name); - } - } - else { - LOG_WARN_STR ("Could not reconnect to parent " << - parent->name << ", deleting entry"); -// concrete_release(parent); - itsParentList.erase(parent); - } - } - break; - - case STARTDAEMON_NEWPARENT: { - // a new parent wants us to connect to it, read info. - STARTDAEMONNewparentEvent NPevent(event); - ParentInfo_t parent; - - // construct the state information the parent think we have. - parent.name = NPevent.cntlrName; - parent.port = new GCFTCPPort(*this, NPevent.parentService, - GCFPortInterface::SAP, CONTROLLER_PROTOCOL); - parent.hostname = NPevent.parentHost; - parent.servicename = NPevent.parentService; - parent.requestedState = LDState::CONNECTED; - parent.requestTime = time(0); - parent.currentState = LDState::NOSTATE; - parent.establishTime = 0; - parent.timerID = 0; - parent.nrRetries = -1; // means: not set - ASSERTSTR(parent.port, "Unable to allocate socket for " << NPevent.cntlrName); - - // add parent to the pool and open the connection with the parent - itsParentList.push_back(parent); - dynamic_cast<GCFTCPPort*>(parent.port)->setHostName (parent.hostname); - parent.port->open(); // results in F_CONN of F_DISCONN - LOG_DEBUG_STR("Registered parent "<< parent.name <<" on port "<< parent.port); - - // pass newParent event to mainTask as Connect event - LOG_DEBUG_STR("Sending CONNECT(" << parent.name << ") event to maintask"); - CONTROLConnectEvent request; - request.cntlrName = parent.name; - itsMainTaskPort->sendBack(request); - } - break; - - case CONTROL_CONNECTED: { - // this event can be received from maintask and parent-controllers - // is it the maintask? --> send CONNECT to parent controller. - if (&port == itsMainTaskPort) { - CONTROLConnectedEvent inMsg(event); - PIiter parent = findParent(inMsg.cntlrName); - if (!isParent(parent)) { - LOG_ERROR_STR("Cannot forward CONNECT event for " << inMsg.cntlrName); - break; - } - CONTROLConnectEvent outMsg; - outMsg.cntlrName = inMsg.cntlrName; - parent->port->send(outMsg); - parent->currentState = LDState::CONNECT; - break; - } - - // should be a parentport - PIiter parent = findParent(&port); - if (!isParent(parent)) { - LOG_WARN_STR ("Received CONNECTED event from unknown parent, ignoring"); - break; - } - - // warn operator when we are out of sync with our parent. - if (parent->requestedState != LDState::CONNECTED) { - LOG_WARN_STR ("Received 'CONNECTED' event while requested state is " << - parent->requestedState); - } - // always accept new state because parent thinks we are in this state. - // TODO: when we are already beyond the claiming state should we release - // the claimed resources? - parent->port->cancelTimer(parent->timerID); - parent->timerID = 0; - parent->currentState = LDState::CONNECTED; - parent->establishTime = time(0); - parent->timerID = 0; - parent->nrRetries = -1; - parent->failed = false; - } - break; - - case CONTROL_CLAIM: - case CONTROL_PREPARE: - case CONTROL_RESUME: - case CONTROL_SUSPEND: - case CONTROL_RELEASE: - case CONTROL_FINISHED: - { - // do we know this parent? - PIiter parent = findParent(&port); - if (isParent(parent)) { - LOG_WARN_STR ("Received " << evtstr(event) << - " event from unknown parent, ignoring"); - break; - } - - // warn operator when we are out of sync with our parent. - if (!isLegalSignal(event.signal, parent)) { - LOG_WARN_STR ("Received " << evtstr(event.signal) << - " event while requested state is " << parent->requestedState); - } - - parent->requestedState = requestedState(event.signal); // use stateFlowTable - parent->requestTime = time(0); - doRequestedAction(parent); - } - break; - - default: - LOG_DEBUG ("ParentControl::operational, default"); - status = GCFEvent::NOT_HANDLED; - break; - } - - return (status); -} - -// -// findParent(port) -// -ParentControl::PIiter ParentControl::findParent(GCFPortInterface* aPort) -{ - LOG_TRACE_COND_STR("findParent: " << aPort); - const_PIiter end = itsParentList.end(); - PIiter iter = itsParentList.begin(); - while (iter != end && iter->port != aPort) { - iter++; - } - return (iter); -} - -// -// findParent(timerID) -// -ParentControl::PIiter ParentControl::findParent(uint32 aTimerID) -{ - LOG_TRACE_COND_STR("findParent: " << aTimerID); - const_PIiter end = itsParentList.end(); - PIiter iter = itsParentList.begin(); - while (iter != end && iter->timerID != aTimerID) { - iter++; - } - return (iter); -} - -// -// findParent(name) -// -ParentControl::PIiter ParentControl::findParent(const string& aName) -{ - LOG_TRACE_COND_STR("findParent: " << aName); - const_PIiter end = itsParentList.end(); - PIiter iter = itsParentList.begin(); - while (iter != end && iter->name != aName) { - iter++; - } - return (iter); -} - - } // namespace MainCU -} // namespace LOFAR diff --git a/MAC/APL/MainCU/src/MACScheduler/ParentControl.h b/MAC/APL/MainCU/src/MACScheduler/ParentControl.h deleted file mode 100644 index 33c7c33700e8f9386e357c69136b0ef1a950aaab..0000000000000000000000000000000000000000 --- a/MAC/APL/MainCU/src/MACScheduler/ParentControl.h +++ /dev/null @@ -1,148 +0,0 @@ -//# ParentControl.h: Task that handles and dispatches all controllers events. -//# -//# Copyright (C) 2006 -//# ASTRON (Netherlands Foundation for Research in Astronomy) -//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl -//# -//# This program is free software; you can redistribute it and/or modify -//# it under the terms of the GNU General Public License as published by -//# the Free Software Foundation; either version 2 of the License, or -//# (at your option) any later version. -//# -//# This program is distributed in the hope that it will be useful, -//# but WITHOUT ANY WARRANTY; without even the implied warranty of -//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//# GNU General Public License for more details. -//# -//# You should have received a copy of the GNU General Public License -//# along with this program; if not, write to the Free Software -//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -//# -//# $Id$ - -#ifndef MAINCU_CONTROLLER_H -#define MAINCU_CONTROLLER_H - -// \file -// Task that handles and dispatches all controllers events. - -//# Never #include <config.h> or #include <lofar_config.h> in a header file! -//# Includes -#include <Common/lofar_string.h> -#include <Common/lofar_map.h> -#include <Common/lofar_list.h> -#include <GCF/TM/GCF_Task.h> -#include <GCF/TM/GCF_TCPPort.h> -#include <GCF/TM/GCF_ITCPort.h> -#include <GCF/TM/GCF_TimerPort.h> -#include <APL/APLCommon/APL_Defines.h> -#include <OTDB/OTDBtypes.h> -#include "LDState.h" - -// Avoid 'using namespace' in headerfiles - -namespace LOFAR { - using GCF::TM::GCFTCPPort; - using GCF::TM::GCFITCPort; - using GCF::TM::GCFTimerPort; - using GCF::TM::GCFEvent; - using GCF::TM::GCFTask; - using GCF::TM::GCFPortInterface; - using APLCommon::LDState; - namespace MainCU { - -// \addtogroup MainCU -// @{ - -//# --- Forward Declarations --- -//# classes mentioned as parameter or returntype without virtual functions. -//class ...; - - -// class_description -// ... -class ParentControl : public GCFTask -{ -public: - // the only way to create the object is via instance. - static ParentControl* instance(); - ~ParentControl(); - - // Main controller task should identify itself at ParentControlTask. - // Its gets an ITCport pointer in return. - GCFITCPort* registerTask (GCFTask* mainTask); - -private: - // Copying and default construction is not allowed - ParentControl(); - ParentControl(const ParentControl& that); - ParentControl& operator=(const ParentControl& that); - - // GCFTask statemachine - GCFEvent::TResult initial (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult operational (GCFEvent& event, GCFPortInterface& port); - - - // Note: When the controller is a shared controller it will have multiple - // parents and for each of these parents it must handle its own - // state machine. - typedef struct ParentInfo { - string name; // uniq name we have for the parent - GCFPortInterface* port; // connection with the parent - string hostname; // host the controller runs on - string servicename; // servicename to connect to - LDState::LDstateNr requestedState; // the state the controller requested - time_t requestTime; // time of requested state - LDState::LDstateNr currentState; // the state we reached for that parent - time_t establishTime; // time the current state was reached - int32 nrRetries; // nr of retries performed - uint32 timerID; // timer for this parent - bool failed; // reaching requested state failed. - } ParentInfo_t; - typedef list<ParentInfo_t>::iterator PIiter; - typedef list<ParentInfo_t>::const_iterator const_PIiter; - - // internal routines for managing the ParentInfo pool. - PIiter findParent(GCFPortInterface* port); - PIiter findParent(uint32 timerID); - PIiter findParent(const string& name); - bool isParent (PIiter parentPtr) - { return (parentPtr != itsParentList.end()); } - bool isLegalSignal (uint16 aSignal, PIiter aParent); - LDState::LDstateNr requestedState(uint16 aSignal); - - // Internal routines - void doRequestedAction(PIiter parent); - - - //# --- Datamembers --- - list<ParentInfo_t> itsParentList; // administration of child controller - - GCFTCPPort* itsSDPort; // clientport to StartDaemon - - GCFITCPort* itsMainTaskPort; // gateway to main task - - GCFTimerPort itsTimerPort; // for internal timers - - string itsServiceName; // serviceinfo of program - uint32 itsInstanceNr; - - string itsControllerName; // name to program is known as - - // All actions from the parent task are queued as ParentControlInfo objects - // and handled in the operational stateMachine. -// list<ParentControlInfo> itsActionList; // list of actions to perform. -// uint32 itsActionTimer; // ID of actiontimer. - -// ... - -}; - - -//# --- Inline functions --- - -// @} - } // namespace MainCU -} // namespace LOFAR - -#endif diff --git a/MAC/APL/MainCU/src/Makefile.am b/MAC/APL/MainCU/src/Makefile.am index ae74088b44ce389e4305ecb0a9b567274f3adcf9..95138ffb1a5fbcb0dea43376d1ec848e95afe37a 100644 --- a/MAC/APL/MainCU/src/Makefile.am +++ b/MAC/APL/MainCU/src/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = MACScheduler +SUBDIRS = MACScheduler ObservationControl include $(top_srcdir)/Makefile.common