From 36b4159a02a49f2a93e2f3f17ae548dd8f3c4598 Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Mon, 5 Nov 2012 11:21:11 +0000
Subject: [PATCH] Task #3766: All changes are marked 'QUICK FIX #3633'.

---
 .../include/APL/APLCommon/ControllerDefines.h |  1 +
 .../CEPCU/src/PythonControl/PythonControl.cc  | 64 ++++++++++++++++++-
 .../CEPCU/src/PythonControl/PythonControl.h   |  5 ++
 .../ObservationControl/ObservationControl.cc  | 29 +++++----
 MAC/MACIO/include/MACIO/MACServiceInfo.h      |  3 +
 5 files changed, 87 insertions(+), 15 deletions(-)

diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/ControllerDefines.h b/MAC/APL/APLCommon/include/APL/APLCommon/ControllerDefines.h
index 9828f1ec31b..e9b6ca26679 100644
--- a/MAC/APL/APLCommon/include/APL/APLCommon/ControllerDefines.h
+++ b/MAC/APL/APLCommon/include/APL/APLCommon/ControllerDefines.h
@@ -57,6 +57,7 @@ enum
 	CT_RESULT_MANUAL_REMOVED,
 	CT_RESULT_NO_PARSET,
 	CT_RESULT_UNKNOWN_OBSERVATION,
+	CT_RESULT_PIPELINE_FAILED,			// QUICK FIX #3633
     CT_RESULT_UNSPECIFIED
 };
 
diff --git a/MAC/APL/CEPCU/src/PythonControl/PythonControl.cc b/MAC/APL/CEPCU/src/PythonControl/PythonControl.cc
index ac863758473..219063642ca 100644
--- a/MAC/APL/CEPCU/src/PythonControl/PythonControl.cc
+++ b/MAC/APL/CEPCU/src/PythonControl/PythonControl.cc
@@ -31,6 +31,7 @@
 #include <Common/ParameterRecord.h>
 #include <Common/Exceptions.h>
 #include <Common/SystemUtil.h>
+#include <Common/hexdump.h>
 #include <ApplCommon/LofarDirs.h>
 #include <ApplCommon/StationInfo.h>
 #include <MACIO/MACServiceInfo.h>
@@ -73,6 +74,9 @@ PythonControl::PythonControl(const string&	cntlrName) :
 	itsParentPort		(0),
 	itsTimerPort		(0),
 	itsListener			(0),
+	itsFeedbackListener	(0),					// QUICK FIX #3633
+	itsFeedbackPort		(0),					// QUICK FIX #3633
+	itsFeedbackResult	(CT_RESULT_NO_ERROR),	// QUICK FIX #3633
 	itsPythonPort		(0),
 	itsState			(CTState::NOSTATE),
 	itsFeedbackFile     (""),
@@ -94,7 +98,11 @@ PythonControl::PythonControl(const string&	cntlrName) :
 	itsParentControl = ParentControl::instance();
 
 	itsListener = new GCFTCPPort (*this, "listener", GCFPortInterface::MSPP, CONTROLLER_PROTOCOL);
-	ASSERTSTR(itsListener, "Cannot allocate TCP for server port");
+	ASSERTSTR(itsListener, "Cannot allocate TCP port for server port");
+
+	// QUICK FIX #3633
+	itsFeedbackListener = new GCFTCPPort (*this, "Feedbacklistener", GCFPortInterface::MSPP, CONTROLLER_PROTOCOL);
+	ASSERTSTR(itsFeedbackListener, "Cannot allocate TCP port for feedback");
 
 	// need port for timers.
 	itsTimerPort = new GCFTimerPort(*this, "TimerPort");
@@ -112,6 +120,11 @@ PythonControl::PythonControl(const string&	cntlrName) :
 PythonControl::~PythonControl()
 {
 	LOG_TRACE_OBJ_STR (getName() << " destruction");
+	if (itsListener) 
+		{ itsListener->close(); delete itsListener; }
+
+	if (itsFeedbackListener) 	// QUICK FIX #3633
+		{ itsFeedbackListener->close(); delete itsFeedbackListener; }
 }
 
 //
@@ -249,6 +262,9 @@ GCFEvent::TResult PythonControl::initial_state(GCFEvent& event,
 	switch (event.signal) {
 	case F_ENTRY:
 		itsListener->open();	// will result in F_CONN
+		// QUICK FIX #3633
+		itsFeedbackListener->setPortNumber(MAC_PYTHON_FEEDBACK_QF);
+		itsFeedbackListener->open();	// will result in F_CONN
    		break;
 
     case F_INIT: {
@@ -441,14 +457,56 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 	}
 	break;
 
+	// QUICK FIX #3633
+	case F_ACCEPT_REQ: {
+		ASSERTSTR(&port == itsFeedbackListener, "Incoming connection on main listener iso feedbackListener");
+		itsFeedbackPort = new GCFTCPPort();
+		itsFeedbackPort->init(*this, "feedback", GCFPortInterface::SPP, 0, true);	// raw port
+		if (!itsFeedbackListener->accept(*itsFeedbackPort)) {
+			delete itsFeedbackPort;
+			itsFeedbackPort = 0;
+			LOG_ERROR("Connection with Python feedback FAILED");
+		}
+		else {
+			LOG_INFO("Connection made on feedback port, accepting commands");
+		}
+	} break;
+
 	case F_DISCONNECTED: {
 		port.close();
 		if (&port == itsPythonPort) {
 			LOG_FATAL_STR("Lost connection with Python, going to wait for a new connection");
 			TRAN(PythonControl::waitForConnection_state);
 		}
-	}
-	break;
+		// QUICK FIX #3633
+		if (&port == itsFeedbackPort) {
+			LOG_FATAL_STR("Lost connection with Feedback of PythonFramework.");
+			delete itsFeedbackPort;
+			itsFeedbackPort = 0;
+		}
+	} break;
+	
+	// QUICK FIX #3633
+	case F_DATAIN: {
+		ASSERTSTR(&port == itsFeedbackPort, "Didn't expect raw data on port " << port.getName());
+		char	buf[1024];
+		ssize_t	btsRead = port.recv((void*)&buf[0], 1023);
+		buf[btsRead] = '\0';
+		string	s;
+		hexdump(s, buf, btsRead);
+		LOG_INFO_STR("Received command on feedback port: " << s);
+
+		if (!strcmp(buf, "ABORT")) {
+			itsFeedbackResult = CT_RESULT_PIPELINE_FAILED;
+			TRAN(PythonControl::finishing_state);
+		}
+		else if (!strcmp(buf, "FINISHED")) {
+			TRAN(PythonControl::finishing_state);
+		}
+		else {
+			LOG_ERROR_STR("Received command on feedback port unrecognized");
+		}
+	} break;
 
 	case DP_CHANGED:
 		_databaseEventHandler(event);
diff --git a/MAC/APL/CEPCU/src/PythonControl/PythonControl.h b/MAC/APL/CEPCU/src/PythonControl/PythonControl.h
index 1c5b8df36ba..f07c3fce92c 100644
--- a/MAC/APL/CEPCU/src/PythonControl/PythonControl.h
+++ b/MAC/APL/CEPCU/src/PythonControl/PythonControl.h
@@ -102,6 +102,11 @@ private:
 
 	GCFTCPPort*				itsListener;
 
+	// QUICK FIX #3633
+	GCFTCPPort*				itsFeedbackListener;
+	GCFTCPPort*				itsFeedbackPort;
+	int						itsFeedbackResult;
+
 	GCFTCPPort*				itsPythonPort;
 	string					itsPythonName;
 	// Until the python pipeline can communicate we can 'fake' the communication by setting the variable to FALSE
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
index 2a168081b57..9cede9a2715 100644
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
@@ -700,17 +700,22 @@ void ObservationControl::setObservationTimers(double	minimalDelay)
 	}
 
 	// (re)set the stop timer
-	if (itsState < CTState::RELEASE) { 				// not yet shutting down?
-		if (sec2stop > 0) {
-			itsStopTimer = itsTimerPort->setTimer((sec2stop < minimalDelay) ? minimalDelay : 1.0 * sec2stop);
-			// make sure we go down 30 seconds after quit was requested.
-			itsForcedQuitTimer = itsTimerPort->setTimer(sec2stop + (1.0 * itsForcedQuitDelay));
-			LOG_INFO_STR ("Observation stops over " << sec2stop << " seconds");
-		}
-		else {
-			assumedState = CTState::RELEASE;
-			LOG_INFO_STR ("Observation should have been stopped " << -sec2start << 
-							" seconds AGO!");
+	if (itsProcessType == "Pipeline") {		// QUICK FIX #3633
+		LOG_INFO("NOT SETTING STOP_TIMERS BECAUSE WE ARE RUNNING A PIPELINE!");
+	}
+	else {
+		if (itsState < CTState::RELEASE) { 				// not yet shutting down?
+			if (sec2stop > 0) {
+				itsStopTimer = itsTimerPort->setTimer((sec2stop < minimalDelay) ? minimalDelay : 1.0 * sec2stop);
+				// make sure we go down 30 seconds after quit was requested.
+				itsForcedQuitTimer = itsTimerPort->setTimer(sec2stop + (1.0 * itsForcedQuitDelay));
+				LOG_INFO_STR ("Observation stops over " << sec2stop << " seconds");
+			}
+			else {
+				assumedState = CTState::RELEASE;
+				LOG_INFO_STR ("Observation should have been stopped " << -sec2start << 
+								" seconds AGO!");
+			}
 		}
 	}
 
@@ -753,7 +758,7 @@ void  ObservationControl::doHeartBeatTask()
 		uint32	nrStations = itsChildControl->countChilds(0, CNTLRTYPE_STATIONCTRL);
 		time_t	now   = to_time_t(second_clock::universal_time());
 		time_t	stop  = to_time_t(itsStopTime);
-		if (now < stop && itsProcessType == "Observation" && itsChildControl->countChilds(0, CNTLRTYPE_STATIONCTRL)==0) {
+		if (now < stop && itsProcessType == "Observation" && !nrStations) {
 			LOG_FATAL("Too less stations left, FORCING QUIT OF OBSERVATION");
 			if (itsState < CTState::RESUME) {
 				itsQuitReason = CT_RESULT_LOST_CONNECTION;
diff --git a/MAC/MACIO/include/MACIO/MACServiceInfo.h b/MAC/MACIO/include/MACIO/MACServiceInfo.h
index 453c8406403..61912266983 100644
--- a/MAC/MACIO/include/MACIO/MACServiceInfo.h
+++ b/MAC/MACIO/include/MACIO/MACServiceInfo.h
@@ -42,6 +42,9 @@ namespace LOFAR {
 #define	MAC_CODELOGGING_PORT			23999
 #define	MAC_SERVICEBROKER_PORT			24000
 
+// QUICK FIX #3633
+#define MAC_PYTHON_FEEDBACK_QF			23932
+
 // CEPlogprocessor needs fixed ports
 #define CEP_LOGPROC_LOGGING				23900
 #define CEP_LOGPROC_CONTROL				23901
-- 
GitLab