# Author: Guillaume Boulant (EDF/R&D)
+#
+# WARNING: development notes
+#
+# This python module is aimed to be a (yet another?) end user
+# interface to manipulate the KERNEL SALOME services. Note that it
+# does not replace the salome module (i.e. what you get when typing
+# "import salome", actually implemented in the file __init__.py of the
+# salome python package). It provides instead functions that help to
+# use the salome module in a end user context (development of domain
+# specific tools by programmers that are not ten years experienced in
+# SALOME development).
import salome
if salome.lcc is None:
salome.salome_init()
except RuntimeError, e:
print e
-
+
+# Note that the salome module provides you with standard SALOME
+# objects: CORBA broker (orb): salome.orb lyfe cycle (lcc) :
+# salome.lcc naming service : salome.naming_service study manager :
+# salome.myStudyManager The default study : salome.myStudy
+#
+# Alternatively, you may obtain these objects directly with the
+# following instructions:
+#
+# from omniORB import CORBA
+# from LifeCycleCORBA import LifeCycleCORBA
+# orb = CORBA.ORB_init( [''], CORBA.ORB_ID )
+# lcc = LifeCycleCORBA( orb )
+#
+# from SALOME_NamingServicePy import SALOME_NamingServicePy_i
+# naming_service = SALOME_NamingServicePy_i( orb )
+#
+# (See salome.py page in the KERNEL documentation)
+
#
# ==============================================================================
# Helper functions for SALOME components
def getComponent(componentName = "SalomeTestComponent",
corbaModule = "Engines",
containerType = "FactoryServer"):
+ """
+ Get a SALOME CORBA component from its name
+ """
print "INF: getting component %s from CORBA module %s ..."%(componentName,corbaModule)
__import__(corbaModule)
component=salome.lcc.FindOrLoadComponent(containerType,componentName)
# the list of components defined in the current session.
import SALOME_ModuleCatalog
def getComponentList():
+ """
+ Get the list of names of all SALOME componenents register in
+ the catalog.
+ """
obj = salome.naming_service.Resolve('Kernel/ModulCatalog')
catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog)
if not catalog:
raise RuntimeError, "Can't accesss module catalog"
return catalog.GetComponentList()
+import SALOMEDS
+def getStudyManager():
+ """
+ Get a study manager to create and manage SALOME studies. WARN: you
+ should use instead the variable salome.myStudyManager. This
+ function is given for illustration of usage of the naming service
+ """
+ import SALOMEDS
+ naming_service = SALOME_NamingServicePy_i( orb )
+ obj = naming_service.Resolve( '/myStudyManager' )
+ studyManager = obj._narrow( SALOMEDS.StudyManager)
+ return studyManager
+
+
#
# ==============================================================================
# Basic use cases and unit tests
if __name__ == "__main__":
import unittester
- unittester.run("salome/kernel/__init__","TEST_getComponent")
- unittester.run("salome/kernel/__init__","TEST_getComponentList")
+ unittester.run("services","TEST_getComponent")
+ unittester.run("services","TEST_getComponentList")
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# 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.
+#
+# 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
+#
+
+__author__="gboulant"
+__date__ ="$1 avr. 2010 18:12:38$"
+
+import time
+import threading
+
+# ===========================================================================
+class Runner(threading.Thread):
+ """
+ This class provides a tool to run and drive a function in a dedicated thread.
+ """
+ def __init__(self, functionToRun=None,*argv):
+ threading.Thread.__init__( self )
+ self._stopevent = threading.Event()
+ self.setFunction(functionToRun)
+ self.setArguments(*argv)
+ self._exception = None
+ self._return = None
+ self._observer = None
+ self._callbackFunction = None
+ # We create an id from the name and the time date in milliseconds
+ self._id = functionToRun.__name__ +"/"+ str(time.time())
+
+ def setFunction(self,functionToRun):
+ """
+ Positionne la fonction � ex�cuter. La fonction peut �tre la
+ m�thode d'un objet pass�e sous la forme 'monobjet.mamethode'.
+ """
+ self.clear()
+ self._function = functionToRun
+
+ def setArguments(self,*argv):
+ """
+ Positionne les arguments � passer � la fonction
+ """
+ self.clear()
+ self._argv = argv
+
+ def getReturn(self):
+ """
+ Retourne le resultat de la fonction. En cas d'erreur, on
+ r�cup�rera l'exception lev�e au moyen de la m�thode
+ getException().
+ """
+ return self._return
+
+ def setCallbackFunction(self, callbackFunction):
+ self._callbackFunction = callbackFunction
+
+ def setObserver(self, observerToNotify):
+ """
+ Permet de sp�cifier un observateur � notifier en fin
+ d'ex�cution. L'observateur est suppos� �tre un objet qui
+ impl�mente une m�thode processNotification()
+ """
+ try:
+ observerToNotify.processNotification
+ except AttributeError:
+ raise DevelException("The observer should implement the method processNotification()")
+
+ self._observer = observerToNotify
+
+ def run(self):
+ """
+ Ex�cution de la fonction. Impl�mentation de la m�thode run
+ d�clench�e par l'appel � Thread.start().
+ """
+ print "##################### threadhelper.run"
+ if self._function is None: return
+ try:
+ self._return = self._function(*self._argv)
+ except Exception, e:
+ print e
+ self._exception = e
+ self._stopevent.set()
+ self.notifyObserver()
+ self.callback()
+ # _GBO_ Maybe it's no use to have both observers and a callback function.
+ # One of the two mechanism should be sufficient
+
+ def notifyObserver(self):
+ if self._observer is None:
+ # Aucune notification pr�vue
+ return
+ try:
+ self._observer.processNotification()
+ except AttributeError, att:
+ if str(att) == "processNotification":
+ print "L'observateur n'impl�mente pas la m�thode processNotification()"
+ else:
+ print "La fonction processNotification() a lev� une exception:"
+ print att
+ except Exception, e:
+ print "La fonction processNotification() a lev� une exception:"
+ print e
+
+ def callback(self):
+ if self._callbackFunction is None: return
+ self._callbackFunction()
+
+ def isEnded(self):
+ """
+ Retourne true si la fonction s'est termin�e naturellement
+ (correctement ou en erreur). Utile pour les client qui
+ pratique le pooling (interrogation r�p�t�e � intervalle
+ r�gulier.
+ """
+ return self._stopevent.isSet()
+ # _GBO_ On n'utilise pas isAlive() pour pouvoir ma�triser
+ # l'indicateur de stop (exemple de la fonction kill)
+ # return not self.isAlive()
+
+ def getException(self):
+ return self._exception
+
+ def getId(self):
+ return self._id
+
+ def wait(self,timeout=None):
+ """
+ Met fin au thread apr�s timeout seconde s'il est encore en
+ ex�cution.
+ Si le compte-�-rebours est atteind sans que la fonction
+ functionToRun soit termin�e, alors le runner est laiss� dans
+ l'�tat 'not Ended', c'est-�-dire que isEnded retourne
+ false. On peut ainsi distinguer l'arr�t normal de l'arr�t �
+ l'issue du timeout.
+ """
+ threading.Thread.join(self, timeout)
+
+
+ def kill(self,message="Arr�t demand�"):
+ """
+ Cette m�thode doit �tre appeler pour interrombre le
+ thread. Cet appel d�clare le thread comme en erreur (exception
+ mise � disposition par la m�thode getException().
+ """
+ # On cr�e un exception indiquant la demande d'interruption
+ self._exception = Exception(message)
+ self._stopevent.set()
+ # _GBO_ ATTENTION
+ # Un thread python ne peut pas en r�alit� �tre int�rrompu.
+ # La fonction reste donc en ex�cution m�me si on a rejoint le
+ # thread appelant.
+
+ def clear(self):
+ self._stopevent.clear()
+ self._exception = None
+ self._return = None
+
+# ===========================================================================
+CONTINUE=1
+STOP=0
+
+class PeriodicTimer( threading.Thread ):
+ """
+ Cette classe permet d'amorcer un compte-�-rebours p�riodique pour
+ op�rer un m�canisme de pooling. On d�finit la fonction appell�e
+ p�riodiquement et la fonction terminale.
+ """
+ def __init__( self, loopdelay, initdelay=0,
+ periodic_action=None,
+ ended_action=None,
+ *ended_argv ):
+
+ if periodic_action is None:
+ self._periodic_action = self.defaultPeriodicAction
+ else:
+ self._periodic_action = periodic_action
+ self._ended_action = ended_action
+ self._loopdelay = loopdelay
+ self._initdelay = initdelay
+ self._running = CONTINUE
+ self._ended_argv = ended_argv
+ threading.Thread.__init__( self )
+
+ def defaultPeriodicAction():
+ """
+ Les fonctions 'periodicAction' retournent CONTINU ou STOP
+ apr�s avoir ex�cut� l'action de fin de boucle. Si STOP est
+ retourn�, le cycle est interrompu.
+ """
+ return CONTINU
+
+ def run( self ):
+ if self._initdelay:
+ time.sleep( self._initdelay )
+ self._runtime = time.time()
+ while self._running == CONTINUE:
+ start = time.time()
+ self._running = self._periodic_action()
+ self._runtime += self._loopdelay
+ time.sleep( max( 0, self._runtime - start ) )
+ if self._ended_action is not None:
+ self._ended_action( *self._ended_argv )
+
+ def stop( self ):
+ self._running = STOP
+
+
+
+#
+# ======================================================
+# Fonctions de test unitaire
+# ======================================================
+#
+
+# ======================================================
+import os
+testfilename="/tmp/threadhelperTestFile"
+def testIfContinue():
+ print "On examine la pr�sence du fichier ", testfilename
+ if os.path.exists(testfilename):
+ return STOP
+ else:
+ return CONTINUE
+
+def endedAction():
+ print "FINI"
+
+def TEST_PeriodicTimer():
+ periodicTimer=PeriodicTimer(1,0,testIfContinue, endedAction)
+ periodicTimer.start()
+
+
+# ======================================================
+def function_ok(nbsteps=5):
+ """
+ Fonction qui se termine correctement
+ """
+ print "D�but"
+ cnt=0
+ while ( cnt < nbsteps ):
+ print "Etape ", cnt
+ time.sleep(0.6)
+ cnt+=1
+
+ print "Fin"
+
+def function_with_exception():
+ """
+ Fonction qui aboutie � une lev�e d'exception
+ """
+ print "D�but"
+ cnt=0
+ while ( cnt < 5 ):
+ print "Etape ", cnt
+ time.sleep(1)
+ cnt+=1
+
+ raise Exception("erreur d'ex�cution de la fonction")
+ print "Fin"
+
+def infinite_function():
+ """
+ fonction de dur�e infinie (tant qu'il y a du courant �l�ctrique) pour
+ le test du timeout.
+ """
+ print "D�but"
+ cnt=0
+ while ( 1 ):
+ print "Etape ", cnt
+ time.sleep(1)
+ cnt+=1
+
+ raise Exception("erreur")
+ print "Fin"
+
+
+def runWithRunner(functionToRun):
+ """
+ Ex�cute la fonction avec le runner. On illustre ici la modalit�
+ d'utilisation du Runner.
+ """
+ print "###########"
+ runner = Runner(functionToRun)
+ runner.start()
+
+ while ( not runner.isEnded() ):
+ print "La fonction est en cours"
+ time.sleep(0.2)
+ e = runner.getException()
+ if e is not None:
+ print "La fonction s'est termin�e en erreur"
+ print e
+ # On peut en fait la relancer
+ # raise e
+ else:
+ print "La fonction s'est termin�e correctement"
+
+
+def runWithTimeout(functionToRun, timeout=10):
+ """
+ Ex�cute la fonction avec le runner. On illustre ici la modalit�
+ d'utilisation du Runner.
+ """
+ print "runWithTimeout : DEBUT"
+ runner = Runner(functionToRun)
+ runner.start()
+
+ # On se fixe un temps au del� duquel on consid�re que la fonction
+ # est en erreur => on tue le thread (timeout)
+ runner.wait(timeout)
+ print "Apr�s runner.timeout(timeout)"
+ if not runner.isEnded():
+ runner.kill()
+ e = runner.getException()
+ if e is not None:
+ print "La fonction s'est termin�e en erreur"
+ print e
+ # On peut en fait la relancer
+ # raise e
+ else:
+ print "La fonction s'est termin�e correctement"
+
+ print "runWithTimeout : FIN"
+ import sys
+ sys.exit(0)
+
+
+def TEST_Timeout():
+ #runWithTimeout(function_ok)
+ #runWithTimeout(function_ok,2)
+ runWithTimeout(function_with_exception)
+
+
+def TEST_Runner():
+ runWithRunner(function_ok)
+ runWithRunner(function_with_exception)
+ #runWithRunner(infinite_function)
+
+
+def myCallbackFunction():
+ print "myCallbackFunction: the job is ended"
+
+
+def TEST_runWithCallback():
+ runner = Runner(function_ok,8)
+ runner.setCallbackFunction(myCallbackFunction)
+ runner.start()
+
+ if runner.getException() is not None:
+ return False
+
+ runnerId = runner.getId()
+ print "A runner has been started with id="+str(runnerId)
+ cpt = 0
+ while ( not runner.isEnded() ):
+ print "Waiting notification from process "+str(runner.getId())+", step n°"+str(cpt)
+ time.sleep(0.2)
+ cpt+=1
+
+ return True
+
+if __name__ == "__main__":
+ import unittester
+ #TEST_PeriodicTimer()
+ #TEST_Runner()
+ #TEST_Timeout()
+ unittester.run("threadhelper","TEST_runWithCallback")
+
+