static constexpr char OUT_OF_PROCESS_NO_REPLAY_VALUE_STR[] = "OutOfProcessNoReplay";
static constexpr char OUT_OF_PROCESS_WITH_REPLAY_VALUE = 2;
static constexpr char OUT_OF_PROCESS_WITH_REPLAY_VALUE_STR[] = "OutOfProcessWithReplay";
+ static constexpr char OUT_OF_PROCESS_NO_REPLAY_FT_VALUE = 3;
+ static constexpr char OUT_OF_PROCESS_NO_REPLAY_FT_VALUE_STR[] = "OutOfProcessNoReplayFT";
+ static constexpr char OUT_OF_PROCESS_WITH_REPLAY_FT_VALUE = 4;
+ static constexpr char OUT_OF_PROCESS_WITH_REPLAY_FT_VALUE_STR[] = "OutOfProcessWithReplayFT";
static PyExecutionMode FromIntToPyExecutionMode(char value)
{
return PyExecutionMode::OutOfProcessNoReplay;
case OUT_OF_PROCESS_WITH_REPLAY_VALUE:
return PyExecutionMode::OutOfProcessWithReplay;
+ case OUT_OF_PROCESS_NO_REPLAY_FT_VALUE:
+ return PyExecutionMode::OutOfProcessNoReplayFT;
+ case OUT_OF_PROCESS_WITH_REPLAY_FT_VALUE:
+ return PyExecutionMode::OutOfProcessWithReplayFT;
}
throw std::range_error("FromIntToPyExecutionMode : Invalid value for Py Execution Mode ! Must be in 0 (InProcess), 1 (OutOfProcessNoReplay) or 2 (OutOfProcessWithReplay) !");
}
return PyExecutionMode::OutOfProcessNoReplay;
if(value == OUT_OF_PROCESS_WITH_REPLAY_VALUE_STR)
return PyExecutionMode::OutOfProcessWithReplay;
+ if(value == OUT_OF_PROCESS_NO_REPLAY_FT_VALUE_STR)
+ return PyExecutionMode::OutOfProcessNoReplayFT;
+ if(value == OUT_OF_PROCESS_WITH_REPLAY_FT_VALUE_STR)
+ return PyExecutionMode::OutOfProcessWithReplayFT;
throw std::range_error("FromStrToPyExecutionMode : Invalid str value for py execution mode !");
}
return OUT_OF_PROCESS_NO_REPLAY_VALUE_STR;
case PyExecutionMode::OutOfProcessWithReplay:
return OUT_OF_PROCESS_WITH_REPLAY_VALUE_STR;
+ case PyExecutionMode::OutOfProcessNoReplayFT:
+ return OUT_OF_PROCESS_NO_REPLAY_FT_VALUE_STR;
+ case PyExecutionMode::OutOfProcessWithReplayFT:
+ return OUT_OF_PROCESS_WITH_REPLAY_FT_VALUE_STR;
default:
throw std::range_error("FromExecutionModeToStr : Invalid str value for py execution mode !");
}
namespace SALOME
{
- enum class PyExecutionMode { NotSet, InProcess, OutOfProcessNoReplay, OutOfProcessWithReplay };
+ enum class PyExecutionMode { NotSet, InProcess, OutOfProcessNoReplay, OutOfProcessWithReplay, OutOfProcessNoReplayFT, OutOfProcessWithReplayFT };
void BASICS_EXPORT SetPyExecutionMode(PyExecutionMode mode);
void BASICS_EXPORT SetPyExecutionModeStr(const std::string& mode);
std::vector<std::string> BASICS_EXPORT GetAllPyExecutionModes();
ADD_EXECUTABLE(SALOME_Container_No_NS_Serv_OutProcess_Replay SALOME_Container_No_NS_Serv_OutProcess_Replay.cxx)
TARGET_LINK_LIBRARIES(SALOME_Container_No_NS_Serv_OutProcess_Replay SalomeContainerServer)
+ADD_EXECUTABLE(SALOME_Container_No_NS_Serv_OutProcess_FT SALOME_Container_No_NS_Serv_OutProcess_FT.cxx)
+TARGET_LINK_LIBRARIES(SALOME_Container_No_NS_Serv_OutProcess_FT SalomeContainerServer)
+
+ADD_EXECUTABLE(SALOME_Container_No_NS_Serv_OutProcess_Replay_FT SALOME_Container_No_NS_Serv_OutProcess_Replay_FT.cxx)
+TARGET_LINK_LIBRARIES(SALOME_Container_No_NS_Serv_OutProcess_Replay_FT SalomeContainerServer)
+
IF(SALOME_BUILD_TESTS)
ADD_EXECUTABLE(TestSalome_file TestSalome_file.cxx)
TARGET_LINK_LIBRARIES(TestSalome_file SALOMETraceCollectorTest ${SALOME_Container_LIBS})
ENDIF()
-INSTALL(TARGETS SALOME_Container SALOME_Container_No_NS_Serv SALOME_Container_No_NS_Serv_OutProcess SALOME_Container_No_NS_Serv_OutProcess_Replay DESTINATION ${SALOME_INSTALL_BINS})
+INSTALL(TARGETS SALOME_Container SALOME_Container_No_NS_Serv SALOME_Container_No_NS_Serv_OutProcess SALOME_Container_No_NS_Serv_OutProcess_Replay SALOME_Container_No_NS_Serv_OutProcess_FT SALOME_Container_No_NS_Serv_OutProcess_Replay_FT DESTINATION ${SALOME_INSTALL_BINS})
# Executable scripts to be installed
SALOME_INSTALL_SCRIPTS("${SCRIPTS}" ${SALOME_INSTALL_SCRIPT_PYTHON})
def getPyScriptCls(self):
return SALOME_PyNode.PyScriptNode_OutOfProcess_Replay_i
+
+class SALOME_Container_OutOfProcess_FT_i(SALOME_Container_i):
+ def __init__(self, containerName, containerIORStr, dftTimeIntervalInMs):
+ super().__init__(containerName, containerIORStr, dftTimeIntervalInMs)
+
+ def getPyScriptCls(self):
+ return SALOME_PyNode.PyScriptNode_OutOfProcess_FT_i
+
+class SALOME_Container_OutOfProcess_Replay_FT_i(SALOME_Container_i):
+ def __init__(self, containerName, containerIORStr, dftTimeIntervalInMs):
+ super().__init__(containerName, containerIORStr, dftTimeIntervalInMs)
+
+ def getPyScriptCls(self):
+ return SALOME_PyNode.PyScriptNode_OutOfProcess_Replay_FT_i
return "SALOME_Container_No_NS_Serv_OutProcess";
case SALOME::PyExecutionMode::OutOfProcessWithReplay:
return "SALOME_Container_No_NS_Serv_OutProcess_Replay";
+ case SALOME::PyExecutionMode::OutOfProcessNoReplayFT:
+ return "SALOME_Container_No_NS_Serv_OutProcess_FT";
+ case SALOME::PyExecutionMode::OutOfProcessWithReplayFT:
+ return "SALOME_Container_No_NS_Serv_OutProcess_Replay_FT";
default:
{
ERROR_MESSAGE("Not manager py execution mode");
#include "SALOME_Container_No_NS_Serv_Generic.hxx"
-GENERIC_CONTAINER_EXECUTABLE( Engines_Container_SSL_i )
+int main(int argc, char* argv[])
+{
+ return GenericContainerExecutable<Engines_Container_SSL_i>(argc,argv);
+}
#include "SALOME_KernelORB.hxx"
#include "KernelBasis.hxx"
-#define GENERIC_CONTAINER_EXECUTABLE( cls ) \
-int main(int argc, char* argv[]) \
-{ \
- if(argc<3) \
- THROW_SALOME_EXCEPTION( "SALOME_Container_No_NS_Serv : requires 2 input arguments <containerName> <IOR of Engines::EmbeddedNamingService>" ); \
- CORBA::ORB_ptr orb(KERNEL::getORB()); \
- std::string IOROfEmbeddedNamingService(argv[2]); \
- setIOROfEmbeddedNS(IOROfEmbeddedNamingService); \
- CORBA::Object_var ns_serv_obj_base = orb->string_to_object(IOROfEmbeddedNamingService.c_str()); \
- if( CORBA::is_nil(ns_serv_obj_base) ) \
- THROW_SALOME_EXCEPTION( "SALOME_Container_No_NS_Serv : argument 2 is NOT a valid IOR" ); \
- Engines::EmbeddedNamingService_var ns_serv_obj = Engines::EmbeddedNamingService::_narrow(ns_serv_obj_base); \
- if( CORBA::is_nil(ns_serv_obj) ) \
- THROW_SALOME_EXCEPTION( "SALOME_Container_No_NS_Serv : argument 2 is NOT a valid IOR of Engines::EmbeddedNamingService" ); \
- std::unique_ptr<SALOME_NamingService_Container_Abstract> ns( new SALOME_Embedded_NamingService_Client(ns_serv_obj) ); \
- return container_common_main<cls>(argc,argv,std::move(ns)); \
+template<class CLS>
+int GenericContainerExecutable(int argc, char* argv[])
+{
+ if(argc<3)
+ THROW_SALOME_EXCEPTION( "SALOME_Container_No_NS_Serv : requires 2 input arguments <containerName> <IOR of Engines::EmbeddedNamingService>" );
+ CORBA::ORB_ptr orb(KERNEL::getORB());
+ std::string IOROfEmbeddedNamingService(argv[2]);
+ setIOROfEmbeddedNS(IOROfEmbeddedNamingService);
+ CORBA::Object_var ns_serv_obj_base = orb->string_to_object(IOROfEmbeddedNamingService.c_str());
+ if( CORBA::is_nil(ns_serv_obj_base) )
+ THROW_SALOME_EXCEPTION( "SALOME_Container_No_NS_Serv : argument 2 is NOT a valid IOR" );
+ Engines::EmbeddedNamingService_var ns_serv_obj = Engines::EmbeddedNamingService::_narrow(ns_serv_obj_base);
+ if( CORBA::is_nil(ns_serv_obj) )
+ THROW_SALOME_EXCEPTION( "SALOME_Container_No_NS_Serv : argument 2 is NOT a valid IOR of Engines::EmbeddedNamingService" );
+ std::unique_ptr<SALOME_NamingService_Container_Abstract> ns( new SALOME_Embedded_NamingService_Client(ns_serv_obj) );
+ return container_common_main<CLS>(argc,argv,std::move(ns));
}
#include "SALOME_Container_No_NS_Serv_Generic.hxx"
-GENERIC_CONTAINER_EXECUTABLE( Engines_Container_SSL_OutOfProcess_i )
+int main(int argc, char* argv[])
+{
+ return GenericContainerExecutable<Engines_Container_SSL_OutOfProcess_i>(argc,argv);
+}
--- /dev/null
+// Copyright (C) 2021-2024 CEA, EDF
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SALOME_Container_No_NS_Serv_Generic.hxx"
+
+int main(int argc, char* argv[])
+{
+ return GenericContainerExecutable<Engines_Container_SSL_OutOfProcess_FT_i>(argc,argv);
+}
#include "SALOME_Container_No_NS_Serv_Generic.hxx"
-GENERIC_CONTAINER_EXECUTABLE( Engines_Container_SSL_OutOfProcess_Replay_i )
+int main(int argc, char* argv[])
+{
+ return GenericContainerExecutable<Engines_Container_SSL_OutOfProcess_Replay_i>(argc,argv);
+}
--- /dev/null
+// Copyright (C) 2021-2024 CEA, EDF
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SALOME_Container_No_NS_Serv_Generic.hxx"
+
+int main(int argc, char* argv[])
+{
+ return GenericContainerExecutable<Engines_Container_SSL_OutOfProcess_Replay_FT_i>(argc,argv);
+}
constexpr char PY_CONTAINER_CLS_NAME_IN_PROCESS[] = "SALOME_Container_i";
constexpr char PY_CONTAINER_CLS_NAME_OUT_PROCESS_NO_REPLAY[] = "SALOME_Container_OutOfProcess_i";
constexpr char PY_CONTAINER_CLS_NAME_OUT_PROCESS_WITH_REPLAY[] = "SALOME_Container_OutOfProcess_Replay_i";
-
+constexpr char PY_CONTAINER_CLS_NAME_OUT_PROCESS_NO_REPLAY_FT[] = "SALOME_Container_OutOfProcess_FT_i";
+constexpr char PY_CONTAINER_CLS_NAME_OUT_PROCESS_WITH_REPLAY_FT[] = "SALOME_Container_OutOfProcess_Replay_FT_i";
class CONTAINER_EXPORT Engines_Container_i : public Abstract_Engines_Container_i
{
Abstract_Engines_Container_SSL_i(PY_CONTAINER_CLS_NAME_OUT_PROCESS_WITH_REPLAY, orb, poa, containerName, argc, argv, ns, isServantAloneInProcess) {}
};
+class CONTAINER_EXPORT Engines_Container_SSL_OutOfProcess_FT_i : public Abstract_Engines_Container_SSL_i
+{
+public:
+ Engines_Container_SSL_OutOfProcess_FT_i(CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ char *containerName,
+ int argc, char *argv[],
+ SALOME_NamingService_Container_Abstract *ns = nullptr,
+ bool isServantAloneInProcess = true) :
+ Abstract_Engines_Container_SSL_i(PY_CONTAINER_CLS_NAME_OUT_PROCESS_NO_REPLAY_FT, orb, poa, containerName, argc, argv, ns, isServantAloneInProcess) {}
+};
+
+class CONTAINER_EXPORT Engines_Container_SSL_OutOfProcess_Replay_FT_i : public Abstract_Engines_Container_SSL_i
+{
+public:
+ Engines_Container_SSL_OutOfProcess_Replay_FT_i(CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ char *containerName,
+ int argc, char *argv[],
+ SALOME_NamingService_Container_Abstract *ns = nullptr,
+ bool isServantAloneInProcess = true) :
+ Abstract_Engines_Container_SSL_i(PY_CONTAINER_CLS_NAME_OUT_PROCESS_WITH_REPLAY_FT, orb, poa, containerName, argc, argv, ns, isServantAloneInProcess) {}
+};
+
/*!
* Methods to be used in SSL mode to skip NS.
*/
{banner}
"""
-def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, keepFilesToReplay, closeEyesOnErrorAtExit = False):
+def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, keepFilesToReplay, closeEyesOnErrorAtExit):
"""
Equivalent of exec(code,context) but executed in a separate subprocess to avoid to make the current process crash.
import CORBA
#
def IsConsideredAsOKRun( returnCode, closeEyesOnErrorAtExit , stderr ):
+ def StdErrTreatment(closeEyesOnErrorAtExit , stderr):
+ if not closeEyesOnErrorAtExit:
+ return stderr
+ else:
+ return stderr[:-len(MY_KEY_TO_DETECT_FINISH)]
if returnCode == 0:
- return True
+ return True,StdErrTreatment(closeEyesOnErrorAtExit , stderr)
if not closeEyesOnErrorAtExit:
- return False
- return stderr[-len(MY_KEY_TO_DETECT_FINISH):] == MY_KEY_TO_DETECT_FINISH
+ return False, stderr
+ return stderr[-len(MY_KEY_TO_DETECT_FINISH):] == MY_KEY_TO_DETECT_FINISH,stderr[:-len(MY_KEY_TO_DETECT_FINISH)]
#
def InternalExecResistant( code, context, outargsname):
return os.path.splitext( os.path.basename(fname)[len(EXEC_CODE_FNAME_PXF):] )[0]
with tempfile.NamedTemporaryFile(dir=os.getcwd(),prefix=EXEC_CODE_FNAME_PXF,suffix=".py", mode="w", delete = False) as codeFd:
codeFd.write( code )
- codeFd.write( """
+ if closeEyesOnErrorAtExit:
+ codeFd.write( """
import sys
sys.stderr.write({!r})
sys.stderr.flush()""".format( MY_KEY_TO_DETECT_FINISH ) )
stdout = stdout.decode()
stderr = stderr.decode()
sys.stdout.write( stdout ) ; sys.stdout.flush()
+ isOK, stderr = IsConsideredAsOKRun( returnCode, closeEyesOnErrorAtExit , stderr )
sys.stderr.write( stderr ) ; sys.stderr.flush()
- if IsConsideredAsOKRun( returnCode, closeEyesOnErrorAtExit , stderr ):
+ if isOK:
pcklData = instanceOfLogOfCurrentSession._remote_handle.getObj()
if len(pcklData) > 0:
ret = pickle.loads( pcklData )
raise RuntimeError(f"Subprocess launched {evParams.strDependingOnReturnCode(keepFilesToReplay,returnCode)}stdout :\n{stdout}\nstderr :\n{stderr}")
def ExecCrashProofWithReplay( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ):
- return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, True, True)
+ return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, True, False)
def ExecCrashProofWithoutReplay( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ):
return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, False, False)
+def ExecCrashProofWithReplayFT( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ):
+ return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, True, True)
+
+def ExecCrashProofWithoutReplayFT( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ):
+ return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, False, True)
+
def ExecLocal( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ):
exec( code, context )
return instanceOfLogOfCurrentSession._current_instance
def executeNow(self, outargsname):
return ExecCrashProofWithReplay(self.code,self.context,outargsname,self.my_container,self._current_execution_session)
+
+class PyScriptNode_OutOfProcess_FT_i(PyScriptNode_Abstract_i):
+ def __init__(self, nodeName, code, poa, my_container, logscript):
+ super().__init__(nodeName, code, poa, my_container, logscript)
+
+ def executeNow(self, outargsname):
+ return ExecCrashProofWithoutReplayFT(self.code,self.context,outargsname,self.my_container,self._current_execution_session)
+
+class PyScriptNode_OutOfProcess_Replay_FT_i(PyScriptNode_Abstract_i):
+ def __init__(self, nodeName, code, poa, my_container, logscript):
+ super().__init__(nodeName, code, poa, my_container, logscript)
+
+ def executeNow(self, outargsname):
+ return ExecCrashProofWithReplayFT(self.code,self.context,outargsname,self.my_container,self._current_execution_session)
[EDF29150] : test that we can resist to a crash at exit
"""
salome.salome_init()
- KernelBasis.SetPyExecutionMode("OutOfProcessWithReplay")
+ KernelBasis.SetPyExecutionMode("OutOfProcessWithReplayFT")
hostname = "localhost"
cp = pylauncher.GetRequestForGiveContainer(hostname,"container_crash_test")
salome.cm.SetBigObjOnDiskThreshold(1000)
ret = pyscript.executeSecond(["j"])
ret = pickle.loads( SALOME_PyNode.SeqByteReceiver(ret[0]).data() )
self.assertEqual(ret,27)
+ with open(cont.locallogfilename) as f:
+ self.assertTrue( "WARNING : Following code has generated non zero return code" in f.read() )# should report something into the container
cont.Shutdown()
if __name__ == '__main__':