From 394e993e6c0d3231d33cc7fa59c30509e28cdd28 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Mon, 3 Jun 2024 15:59:11 +0200 Subject: [PATCH] [29150] : Fault tolerant mecanism --- src/Basics/KernelBasis.cxx | 16 ++++++++ src/Basics/KernelBasis.hxx | 2 +- src/Container/CMakeLists.txt | 8 +++- src/Container/SALOME_Container.py | 14 +++++++ src/Container/SALOME_ContainerManager.cxx | 4 ++ src/Container/SALOME_Container_No_NS_Serv.cxx | 5 ++- .../SALOME_Container_No_NS_Serv_Generic.hxx | 32 +++++++-------- ...SALOME_Container_No_NS_Serv_OutProcess.cxx | 5 ++- ...OME_Container_No_NS_Serv_OutProcess_FT.cxx | 25 +++++++++++ ...Container_No_NS_Serv_OutProcess_Replay.cxx | 5 ++- ...tainer_No_NS_Serv_OutProcess_Replay_FT.cxx | 25 +++++++++++ src/Container/SALOME_Container_i.hxx | 27 +++++++++++- src/Container/SALOME_PyNode.py | 41 +++++++++++++++---- src/Launcher/Test/testCrashProofContainer.py | 4 +- 14 files changed, 183 insertions(+), 30 deletions(-) create mode 100644 src/Container/SALOME_Container_No_NS_Serv_OutProcess_FT.cxx create mode 100644 src/Container/SALOME_Container_No_NS_Serv_OutProcess_Replay_FT.cxx diff --git a/src/Basics/KernelBasis.cxx b/src/Basics/KernelBasis.cxx index 649f51556..5789721ad 100644 --- a/src/Basics/KernelBasis.cxx +++ b/src/Basics/KernelBasis.cxx @@ -81,6 +81,10 @@ namespace SALOME 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) { @@ -92,6 +96,10 @@ namespace SALOME 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) !"); } @@ -104,6 +112,10 @@ namespace SALOME 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 !"); } @@ -117,6 +129,10 @@ namespace SALOME 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 !"); } diff --git a/src/Basics/KernelBasis.hxx b/src/Basics/KernelBasis.hxx index cbecfe72e..8399fc76f 100644 --- a/src/Basics/KernelBasis.hxx +++ b/src/Basics/KernelBasis.hxx @@ -37,7 +37,7 @@ void BASICS_EXPORT WriteInStderr(const std::string& msg); 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 BASICS_EXPORT GetAllPyExecutionModes(); diff --git a/src/Container/CMakeLists.txt b/src/Container/CMakeLists.txt index 4eb507ecc..e61ebbb21 100644 --- a/src/Container/CMakeLists.txt +++ b/src/Container/CMakeLists.txt @@ -119,11 +119,17 @@ TARGET_LINK_LIBRARIES(SALOME_Container_No_NS_Serv_OutProcess SalomeContainerServ 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}) diff --git a/src/Container/SALOME_Container.py b/src/Container/SALOME_Container.py index bd267d4dc..a7d2f83c5 100644 --- a/src/Container/SALOME_Container.py +++ b/src/Container/SALOME_Container.py @@ -223,3 +223,17 @@ class SALOME_Container_OutOfProcess_Replay_i(SALOME_Container_i): 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 diff --git a/src/Container/SALOME_ContainerManager.cxx b/src/Container/SALOME_ContainerManager.cxx index be55b1bf3..391c4076d 100644 --- a/src/Container/SALOME_ContainerManager.cxx +++ b/src/Container/SALOME_ContainerManager.cxx @@ -586,6 +586,10 @@ std::string SALOME_ContainerManager::GetCppBinaryOfKernelSSLContainer() const 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"); diff --git a/src/Container/SALOME_Container_No_NS_Serv.cxx b/src/Container/SALOME_Container_No_NS_Serv.cxx index f7df00250..097663605 100644 --- a/src/Container/SALOME_Container_No_NS_Serv.cxx +++ b/src/Container/SALOME_Container_No_NS_Serv.cxx @@ -19,4 +19,7 @@ #include "SALOME_Container_No_NS_Serv_Generic.hxx" -GENERIC_CONTAINER_EXECUTABLE( Engines_Container_SSL_i ) +int main(int argc, char* argv[]) +{ + return GenericContainerExecutable(argc,argv); +} diff --git a/src/Container/SALOME_Container_No_NS_Serv_Generic.hxx b/src/Container/SALOME_Container_No_NS_Serv_Generic.hxx index d5bc1e7f6..bd4932a2f 100644 --- a/src/Container/SALOME_Container_No_NS_Serv_Generic.hxx +++ b/src/Container/SALOME_Container_No_NS_Serv_Generic.hxx @@ -24,20 +24,20 @@ #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 " ); \ - 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 ns( new SALOME_Embedded_NamingService_Client(ns_serv_obj) ); \ - return container_common_main(argc,argv,std::move(ns)); \ +template +int GenericContainerExecutable(int argc, char* argv[]) +{ + if(argc<3) + THROW_SALOME_EXCEPTION( "SALOME_Container_No_NS_Serv : requires 2 input arguments " ); + 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 ns( new SALOME_Embedded_NamingService_Client(ns_serv_obj) ); + return container_common_main(argc,argv,std::move(ns)); } diff --git a/src/Container/SALOME_Container_No_NS_Serv_OutProcess.cxx b/src/Container/SALOME_Container_No_NS_Serv_OutProcess.cxx index f535d073a..c1c02c784 100644 --- a/src/Container/SALOME_Container_No_NS_Serv_OutProcess.cxx +++ b/src/Container/SALOME_Container_No_NS_Serv_OutProcess.cxx @@ -19,4 +19,7 @@ #include "SALOME_Container_No_NS_Serv_Generic.hxx" -GENERIC_CONTAINER_EXECUTABLE( Engines_Container_SSL_OutOfProcess_i ) +int main(int argc, char* argv[]) +{ + return GenericContainerExecutable(argc,argv); +} diff --git a/src/Container/SALOME_Container_No_NS_Serv_OutProcess_FT.cxx b/src/Container/SALOME_Container_No_NS_Serv_OutProcess_FT.cxx new file mode 100644 index 000000000..fdc3d9669 --- /dev/null +++ b/src/Container/SALOME_Container_No_NS_Serv_OutProcess_FT.cxx @@ -0,0 +1,25 @@ +// 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(argc,argv); +} diff --git a/src/Container/SALOME_Container_No_NS_Serv_OutProcess_Replay.cxx b/src/Container/SALOME_Container_No_NS_Serv_OutProcess_Replay.cxx index 27a90f58e..be198b252 100644 --- a/src/Container/SALOME_Container_No_NS_Serv_OutProcess_Replay.cxx +++ b/src/Container/SALOME_Container_No_NS_Serv_OutProcess_Replay.cxx @@ -19,4 +19,7 @@ #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(argc,argv); +} diff --git a/src/Container/SALOME_Container_No_NS_Serv_OutProcess_Replay_FT.cxx b/src/Container/SALOME_Container_No_NS_Serv_OutProcess_Replay_FT.cxx new file mode 100644 index 000000000..7568dea30 --- /dev/null +++ b/src/Container/SALOME_Container_No_NS_Serv_OutProcess_Replay_FT.cxx @@ -0,0 +1,25 @@ +// 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(argc,argv); +} diff --git a/src/Container/SALOME_Container_i.hxx b/src/Container/SALOME_Container_i.hxx index d929939f0..4ade76e5b 100644 --- a/src/Container/SALOME_Container_i.hxx +++ b/src/Container/SALOME_Container_i.hxx @@ -223,7 +223,8 @@ protected: 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 { @@ -289,6 +290,30 @@ public: 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. */ diff --git a/src/Container/SALOME_PyNode.py b/src/Container/SALOME_PyNode.py index 13e477f16..0069e15c7 100644 --- a/src/Container/SALOME_PyNode.py +++ b/src/Container/SALOME_PyNode.py @@ -794,7 +794,7 @@ Looks like a hard crash as returnCode {returnCode} != 0 {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. @@ -825,11 +825,16 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL 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): @@ -841,7 +846,8 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL 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 ) ) @@ -863,8 +869,9 @@ 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 ) @@ -881,11 +888,17 @@ sys.stderr.flush()""".format( MY_KEY_TO_DETECT_FINISH ) ) 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 @@ -1147,3 +1160,17 @@ class PyScriptNode_OutOfProcess_Replay_i(PyScriptNode_Abstract_i): 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) diff --git a/src/Launcher/Test/testCrashProofContainer.py b/src/Launcher/Test/testCrashProofContainer.py index 11ac637ae..6b0ca88a8 100644 --- a/src/Launcher/Test/testCrashProofContainer.py +++ b/src/Launcher/Test/testCrashProofContainer.py @@ -174,7 +174,7 @@ class testPerfLogManager1(unittest.TestCase): [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) @@ -187,6 +187,8 @@ class testPerfLogManager1(unittest.TestCase): 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__': -- 2.39.2