]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
[EDF30062] : tolerance of crash at exit
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 31 May 2024 16:32:46 +0000 (18:32 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 31 May 2024 16:32:46 +0000 (18:32 +0200)
src/Container/SALOME_PyNode.py

index 312c7bf5d94cd29f8273b7a491e2fb79d317816a..13e477f16348c0724e4e2f816cc7ddaa210003c0 100644 (file)
@@ -40,6 +40,8 @@ MY_CONTAINER_ENTRY_IN_GLBS = "my_container"
 
 MY_PERFORMANCE_LOG_ENTRY_IN_GLBS = "my_log_4_this_session"
 
+MY_KEY_TO_DETECT_FINISH = "neib av tuot"
+
 class Generic(SALOME__POA.GenericObj):
   """A Python implementation of the GenericObj CORBA IDL"""
   def __init__(self,poa):
@@ -792,7 +794,7 @@ Looks like a hard crash as returnCode {returnCode} != 0
 {banner}
 """
 
-def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, keepFilesToReplay ):
+def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, keepFilesToReplay, closeEyesOnErrorAtExit = False):
   """
   Equivalent of exec(code,context) but executed in a separate subprocess to avoid to make the current process crash.
   
@@ -805,6 +807,7 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL
   containerRef (Engines.Container) : Container ref (retrieving the Files to created when keepFilesToReplay is set to False)
   instanceOfLogOfCurrentSession (LogOfCurrentExecutionSession) : instance of LogOfCurrentExecutionSession to build remotely the reference in order to log information
   keepFilesToReplay (bool) : if True when something goes wrong during execution all the files to replay post mortem case are kept. If False only error is reported but files to replay are destoyed.
+  closeEyesOnErrorAtExit (bool) : if True in case of crash of subprocess, if MY_KEY_TO_DETECT_FINISH is displayed at the end of stdout
 
   Return:
   -------
@@ -820,6 +823,14 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL
   import pickle
   import subprocess as sp
   import CORBA
+  #
+  def IsConsideredAsOKRun( returnCode, closeEyesOnErrorAtExit , stderr ):
+    if returnCode == 0:
+      return True
+    if not closeEyesOnErrorAtExit:
+      return False
+    return stderr[-len(MY_KEY_TO_DETECT_FINISH):] == MY_KEY_TO_DETECT_FINISH
+
   #
   def InternalExecResistant( code, context, outargsname):
     orb = CORBA.ORB_init([''])
@@ -830,6 +841,10 @@ 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( """
+import sys
+sys.stderr.write({!r})
+sys.stderr.flush()""".format( MY_KEY_TO_DETECT_FINISH ) )
       codeFd.flush()
       codeFileName = os.path.basename( codeFd.name )
       contextFileName = "contextsafe_{}.pckl".format( RetrieveUniquePartFromPfx( codeFileName  ) )
@@ -849,14 +864,16 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL
   stderr = stderr.decode()
   sys.stdout.write( stdout ) ; sys.stdout.flush()
   sys.stderr.write( stderr ) ; sys.stderr.flush()
-  if returnCode == 0:
+  if IsConsideredAsOKRun( returnCode, closeEyesOnErrorAtExit , stderr ):
     pcklData = instanceOfLogOfCurrentSession._remote_handle.getObj()
     if len(pcklData) > 0:
       ret = pickle.loads( pcklData )
     context.update( evParams.result )
     evParams.destroyOnOK()
+    if returnCode != 0:
+      print( "WARNING : Following code has generated non zero return code ( {} ) but considered as OK\n{}".format( returnCode, code ) )
     return ret
-  if returnCode != 0:
+  else:
     if keepFilesToReplay:
       evParams.destroyOnKO( containerRef )
     else:
@@ -864,10 +881,10 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL
     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)
+  return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, True, True)
 
 def ExecCrashProofWithoutReplay( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ):
-  return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, False)
+  return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, False, False)
 
 def ExecLocal( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ):
   exec( code, context )