gump-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From leosim...@apache.org
Subject svn commit: r123529 - in gump/trunk/python/gump/core: run runner
Date Tue, 28 Dec 2004 18:30:15 GMT
Author: leosimons
Date: Tue Dec 28 10:30:14 2004
New Revision: 123529

URL: http://svn.apache.org/viewcvs?view=rev&rev=123529
Log:
Addition of inline documentation, some code refactoring and cleanup, refactoring of logging
to be able to disable it on a class-by-class basis in various files (makes unit testing easier
for one), and some other stuff.
Modified:
   gump/trunk/python/gump/core/run/__init__.py
   gump/trunk/python/gump/core/run/actor.py
   gump/trunk/python/gump/core/run/gumpenv.py
   gump/trunk/python/gump/core/run/gumprun.py
   gump/trunk/python/gump/core/runner/__init__.py
   gump/trunk/python/gump/core/runner/demand.py
   gump/trunk/python/gump/core/runner/runner.py

Modified: gump/trunk/python/gump/core/run/__init__.py
Url: http://svn.apache.org/viewcvs/gump/trunk/python/gump/core/run/__init__.py?view=diff&rev=123529&p1=gump/trunk/python/gump/core/run/__init__.py&r1=123528&p2=gump/trunk/python/gump/core/run/__init__.py&r2=123529
==============================================================================
--- gump/trunk/python/gump/core/run/__init__.py	(original)
+++ gump/trunk/python/gump/core/run/__init__.py	Tue Dec 28 10:30:14 2004
@@ -19,10 +19,25 @@
 # 
 
 """
+Gump works in a batch mode. Doing one iteration of cvs and svn updates
+and then building all the different projects is called a single "gump
+run". Such a run is modelled by gump.core.run.gumprun.GumpRun.
 
-  Gump Run Components.
-  
+A run is split into several stages:
+
+    1) setup work (parsing commands, merging xml files, etc)
+    2) general build work (initializing and setting up helpers,
+       performing per-run tasks)
+    3) per-module and per-project work (ie updates and builds
+       and whatever different "actors" do on a per-module or
+       per-project basis)
+    3) post-build work (cleaning up, sending out e-mail, etc)
+
+Each of these stages is handled by the gump.core.runner package. The
+gump.core.run package defines what should happen during any such run,
+and is the place where the runner and actors keep track of what is
+going on.
 """
 
-# tell Python what modules make up the gump.core package
+# tell Python what modules make up the gump.run package
 __all__ = ["actor","gumpenv","gumprun","options", "gumpset"]

Modified: gump/trunk/python/gump/core/run/actor.py
Url: http://svn.apache.org/viewcvs/gump/trunk/python/gump/core/run/actor.py?view=diff&rev=123529&p1=gump/trunk/python/gump/core/run/actor.py&r1=123528&p2=gump/trunk/python/gump/core/run/actor.py&r2=123529
==============================================================================
--- gump/trunk/python/gump/core/run/actor.py	(original)
+++ gump/trunk/python/gump/core/run/actor.py	Tue Dec 28 10:30:14 2004
@@ -16,7 +16,6 @@
 # limitations under the License.
 
 """
-
 	An actor works upon the context tree. Events (and in the future,
 	perhaps Requests) are passed to the Actor, and the Actor performs
 	it's work.
@@ -33,12 +32,10 @@
 import sys
 from fnmatch import fnmatch
 
-from gump import log
 from gump.core.config import dir, default, basicConfig
 from gump.core.run.gumpenv import GumpEnvironment
 from gump.core.run.gumprun import *
 
-
 from gump.util.work import *
 from gump.util import dump, display, getIndent
 from gump.util.note import Annotatable
@@ -49,28 +46,23 @@
 from gump.core.model.depend import  ProjectDependency
 from gump.core.model.state import *
 
-
-    
-###############################################################################
-# Functions
-###############################################################################
-
-###############################################################################
-# Classes
-###############################################################################
-
-
-        
 class  RunActor(RunSpecific):     
     """
-    
-        An actor acts upon the run result events.
-        
+        Abstract base class for all actors. The gump runner fires off different
+        kinds of "events" (really just bits of the context trees that the gump
+        runner has just updated then built) to the actor.
+        
+        This base class sets up some class properties that are often used in
+        subclasses, and defines a base _processEvent that fires off processEvent
+        on subclasses only if that method exists on the subclass.
     """
     
-    def __init__(self, run):
+    def __init__(self, run, log = None):
         RunSpecific.__init__(self,run)
         
+        if not log: from gump import log
+        self.log = log
+        
         # Oft used references..
         self.workspace=run.getWorkspace()
         self.options=run.getOptions()
@@ -89,13 +81,34 @@
         #log.debug('Process event [' + `event` + '] using [' + `self` + ']')        
         self.processEvent(event)
 
-class AbstractRunActor(RunActor):    
+class AbstractRunActor(RunActor):
+    """
+    Abstract base class for nearly all actors. It acts as a basic event filter,
+    sending different types of events to different methods in the subclass if
+    those are defined. The supported methods are:
     
-    def __init__(self, run):
-        RunActor.__init__(self,run)
-        
+        processRun() -- for events of the GumpRun type. Use this one for doing
+                start-of-run setup work.
+        processWorkspace() -- fed the Workspace for this run after it is fully
+                set up. Use this one for customizing the actor's behaviour
+                based on the workspace and performing any late initialization.
+        processModule() -- fed the Module instance for each and every module that
+                has been processed by the main runner (ie, has been updated).
+        processProject() -- fed the Project instance for each and every project
+                that has been built by the main runnner (whether successful or
+                not).
+        processOtherEvent() -- fed all the other events (ie the ones that
+                AbstractRunActor doesn't know about).
+    """
+    
+    def __init__(self, run, log=None):
+        RunActor.__init__(self, run, log)
         
     def processEvent(self,event):
+        """
+        Event handler that redirects to each of the _processXXXEvent methods,
+        which in turn delegate to processXXXEvent methods on subclasses.
+        """
         
         if isinstance(event,EntityRunEvent):
             entity=event.getEntity()
@@ -112,58 +125,54 @@
         else:
             self._processOtherEvent(event)
             
-            
-    #
-    # Call a method called 'processRun(Run)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
     def _processRun(self):
+        """
+        Call a method called 'processRun(Run)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processRun'): return        
         if not callable(self.processRun):  return        
-        log.debug('Process Run using [' + `self` + ']')        
+        self.log.debug('Process Run using [' + `self` + ']')        
         self.processRun()
         
             
-    #
-    # Call a method called 'processWorkspace(workspace)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
     def _processWorkspace(self,workspace):
+        """
+        Call a method called 'processWorkspace(workspace)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processWorkspace'): return        
         if not callable(self.processWorkspace):  return        
-        log.debug('Process Workspace [' + `workspace` + '] using [' + `self` + ']')     
  
+        self.log.debug('Process Workspace [' + `workspace` + '] using [' + `self` + ']')
       
         self.processWorkspace()
         
-    #
-    # Call a method called 'processModule(module)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
     def _processModule(self,module):
+        """
+        Call a method called 'processModule(module)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processModule'): return        
         if not callable(self.processModule):  return        
-        log.debug('Process Module [' + `module` + '] using [' + `self` + ']')        
+        self.log.debug('Process Module [' + `module` + '] using [' + `self` + ']')      
 
         self.processModule(module)
         
             
-    #
-    # Call a method called 'processProject(Project)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
     def _processProject(self,project):
+        """
+        Call a method called 'processProject(Project)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processProject'): return        
         if not callable(self.processProject):  return        
-        log.debug('Process Project [' + `project` + '] using [' + `self` + ']')        
+        self.log.debug('Process Project [' + `project` + '] using [' + `self` + ']')    
   
         self.processProject(project)
-        
-            
-    #
-    # Call a method called 'processOtherEvent(event)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
+               
     def _processOtherEvent(self,event):
+        """
+        Call a method called 'processOtherEvent(event)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processOtherEvent'): return        
         if not callable(self.processOtherEvent):  return        
-        log.debug('Process (Other) Event [' + `event` + '] using [' + `self` + ']')     
  
+        self.log.debug('Process (Other) Event [' + `event` + '] using [' + `self` + ']')
       
         self.processOtherEvent(event)
-        
-            

Modified: gump/trunk/python/gump/core/run/gumpenv.py
Url: http://svn.apache.org/viewcvs/gump/trunk/python/gump/core/run/gumpenv.py?view=diff&rev=123529&p1=gump/trunk/python/gump/core/run/gumpenv.py&r1=123528&p2=gump/trunk/python/gump/core/run/gumpenv.py&r2=123529
==============================================================================
--- gump/trunk/python/gump/core/run/gumpenv.py	(original)
+++ gump/trunk/python/gump/core/run/gumpenv.py	Tue Dec 28 10:30:14 2004
@@ -1,6 +1,5 @@
 #!/usr/bin/python
-
-
+#
 # Copyright 2003-2004 The Apache Software Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,15 @@
 # limitations under the License.
 
 """
- A gump environment (i.e. what tools are available in this machine's
- environment, and so forth).
+    A gump environment (i.e. what tools are available in this machine's
+    environment, and so forth).
+    
+    TODO: a lot of this stuff needs to be available in other environments
+    as well, for example when we run dynagump or the unit tests we also
+    want to know about our environment. Either this class is refactored so
+    as to be much more decoupled from the rest of gump or we simply move
+    this functionality out into the shell script code so we can get rid of
+    it here.
 """
 
 import os.path
@@ -25,8 +31,6 @@
 from types import NoneType
 from fnmatch import fnmatch
 
-from gump import log
-
 from gump.core.config import *
 
 from gump.util.note import Annotatable
@@ -41,24 +45,28 @@
 from gump.core.model.propagation import *
 
 from gump.tool.integration.depot import *
-    
-###############################################################################
-# Classes
-###############################################################################
 
+#TODO: any reason checkEnvironment can't simply be called once (on __init__)
+#      and after that simply used? It'd certainly simplify the code a bit..
 class GumpEnvironment(Annotatable,Workable,Propogatable):
     """
-    	Represents the environment that Gump is running within.
-    	
-    	What environment variables are set, what tools are 
-    	available, what Java command to use, etc.
+    Represents the environment that Gump is running within.
+    
+    What environment variables are set, what tools are 
+    available, what Java command to use, etc.
+    
+    If some required bit of environment is missing, this class will actually
+    short-circuit gump and call sys.exit.
     """
 
-    def __init__(self):
+    def __init__(self, log = None):
         Annotatable.__init__(self)
         Workable.__init__(self)
         Propogatable.__init__(self)
-        Stateful.__init__(self)
+        #Stateful.__init__(self) -- redundant, already called from Propogatable.__init__
+        
+        if not log: from gump import log
+        self.log = log
         
         self.checked = False
         self.set = False
@@ -93,7 +101,7 @@
         
     def checkEnvironment(self,exitOnError=False):
         """ 
-        Check things that are required/optional 
+        Take a look at the environment and populate this object's properties based on that.
         """
         
         if self.checked: return
@@ -186,7 +194,7 @@
         
     def setEnvironment(self):
         """ 
-        Set things that are required 
+        Customize the actual environment to reflect the way gump needs things to be.
         """
         
         if self.set: return
@@ -219,7 +227,7 @@
         self.checkEnvironment()
         
         if self.noJavac: 
-            log.error("Can't obtain Java properties since Java Environment was not found")
+            self.log.error("Can't obtain Java properties since Java Environment was not found")
             return {}
 
         import commands, re
@@ -252,11 +260,14 @@
         if os.path.exists(JAVA_CLASS): os.unlink(JAVA_CLASS)
 
         for (name,value) in self.javaProperties.items():
-            log.debug("Java Property: " + name + " => " + value)
+            self.log.debug("Java Property: " + name + " => " + value)
 
         return self.javaProperties
 
     def _checkExecutable(self,command,options,mandatory,logOutput=False,name=None):
+        """
+        Determine whether a particular command is or is not available.
+        """
         ok = False
         try:
             if not name: name = 'check_'+command
@@ -264,12 +275,12 @@
             result = execute(cmd)
             ok = result.isOk()
             if ok:
-                log.warning('Detected [' + command + ' ' + options + ']')   
+                self.log.warning('Detected [' + command + ' ' + options + ']')   
             else:
-                log.warning('Failed to detect [' + command + ' ' + options + ']')   
+                self.log.warning('Failed to detect [' + command + ' ' + options + ']')  

         except Exception, details:
             ok = False
-            log.error('Failed to detect [' + command + ' ' + options + '] : ' + str(details))
+            self.log.error('Failed to detect [' + command + ' ' + options + '] : ' + str(details))
             result = None
        
         # Update 
@@ -290,15 +301,18 @@
         return ok
     
     def _checkEnvVariable(self,env,mandatory=True):
+        """
+        Determine whether a particular environment variable is set.
+        """
         ok = False
         try:
             ok = os.environ.has_key(env)
             if not ok:
-                log.info('Failed to find environment variable [' + env + ']')
+                self.log.info('Failed to find environment variable [' + env + ']')
         
         except Exception, details:
             ok = False
-            log.error('Failed to find environment variable [' + env + '] : ' + str(details))
+            self.log.error('Failed to find environment variable [' + env + '] : ' + str(details))
     
         if not ok and mandatory:
             print

Modified: gump/trunk/python/gump/core/run/gumprun.py
Url: http://svn.apache.org/viewcvs/gump/trunk/python/gump/core/run/gumprun.py?view=diff&rev=123529&p1=gump/trunk/python/gump/core/run/gumprun.py&r1=123528&p2=gump/trunk/python/gump/core/run/gumprun.py&r2=123529
==============================================================================
--- gump/trunk/python/gump/core/run/gumprun.py	(original)
+++ gump/trunk/python/gump/core/run/gumprun.py	Tue Dec 28 10:30:14 2004
@@ -24,7 +24,6 @@
  It contains the gumpset (the list of projects/modules to work upon)
  It contains the workspace (metadata)
  It contains the tree of context (run information upon metadata items)
-  
  
 """
 
@@ -33,7 +32,6 @@
 import sys
 import fnmatch
 
-from gump import log
 from gump.core.config import dir, default, basicConfig
 from gump.core.run.gumpenv import GumpEnvironment
 
@@ -50,26 +48,32 @@
 from gump.core.model.depend import  ProjectDependency
 from gump.core.model.state import *
     
-###############################################################################
-# Init
-###############################################################################
-
-###############################################################################
-# Classes
-###############################################################################
-
-
 class GumpRun(gump.util.timing.Timeable,gump.util.work.Workable,gump.util.note.Annotatable,Stateful):
     """
-    The container for all information for this run
+    The container for all information for this run.
+    
+    A GumpRun is "passive", it doesn't really do much of itself. (TODO: refactor
+    so that it does absolutely *nothing*). That is what the gump.core.runner
+    package is for.
+    
+    The GumpRun is pretty central to all the stuff going on during a gump run,
+    obviously. It serves as the main communication point between the runner, its
+    helpers, and all the different actors.
+    
+    TODO: evaluate making this class less central and splitting its various
+          responsibilities into multiple smaller classes. Making this class so
+          central to everything is what promotes most of the "monolithic" feel
+          of the gump architecture right now.
     """
-    def __init__(self,workspace,expr=None,options=None,env=None):
-        
+    def __init__(self,workspace,expr=None,options=None,env=None,log=None):
         gump.util.work.Workable.__init__(self)
         gump.util.note.Annotatable.__init__(self)
         Stateful.__init__(self)
         gump.util.timing.Timeable.__init__(self, workspace.getName())
         
+        if not log: from gump import log
+        self.log = log
+        
         # The workspace being worked upon
         self.workspace=workspace
         
@@ -99,7 +103,7 @@
         self.guid = socket.getfqdn()  + ':' + workspace.getName() + ':' + default.datetime_s
         m.update(self.guid)
         self.hexguid=m.hexdigest().upper()     
-        log.info('Run GUID [' + `self.guid` + '] using [' + `self.hexguid` + ']')    
+        self.log.info('Run GUID [' + `self.guid` + '] using [' + `self.hexguid` + ']')  
 
         
         # Actor Queue
         self.actors=list()
@@ -162,22 +166,22 @@
         self.gumpSet.dump(indent+1,output)
        
     def registerActor(self,actor):
-        log.debug('Register Actor : ' + `actor`)
+        self.log.debug('Register Actor : ' + `actor`)
         self.actors.append(actor)
         
     def logActors(self):
-        log.debug('There are %s registered actors : ' % len(self.actors))       
+        self.log.debug('There are %s registered actors : ' % len(self.actors))       
         for actor in self.actors:
-            log.debug('Registered Actor : ' + `actor`)    
+            self.log.debug('Registered Actor : ' + `actor`)    
             
         
     def _dispatchEvent(self,event):    	
     	"""
     		Perform the dispatch
     	"""
-        log.debug('Dispatch Event : ' + `event`)        
+        self.log.debug('Dispatch Event : ' + `event`)        
         for actor in self.actors:
-            #log.debug('Dispatch Event : ' + `event` + ' to ' + `actor`)     
+            #self.log.debug('Dispatch Event : ' + `event` + ' to ' + `actor`)     
             actor._processEvent(event)
         gump.util.inspectGarbageCollection(`event`)
             
@@ -185,9 +189,9 @@
     	"""
     		Perform the dispatch
     	"""
-        log.debug('Dispatch Request : ' + `request`)    
+        self.log.debug('Dispatch Request : ' + `request`)    
         for actor in self.actors:
-            #log.debug('Dispatch Request : ' + `request` + ' to ' + `actor`)       
+            #self.log.debug('Dispatch Request : ' + `request` + ' to ' + `actor`)       
             actor._processRequest(request)
         gump.util.inspectGarbageCollection(`request`)
             
@@ -212,16 +216,27 @@
         the basis for everything, so many things are specific
         to a single run (for conveinience).
         
+        TODO: this is used both as a "marker interface" and as a
+        general way to get at the global "context" represented by
+        the GumpRun instance. If we can remove it from as many
+        classes as possible that'll promote a *lot* of seperation
+        of concerns and establishment of control barriers.
     """
     def __init__(self, run):
-        self.run    =    run
+        self.run = run
         
     def getRun(self):
         return self.run
 
 class RunEvent(RunSpecific):
     """
-        An event to actors (e.g. a project built, a module updated)
+        An event to actors (e.g. a project built, a module updated).
+        
+        Note that not all events currently passed around are really
+        "events", for example, we pass around actual Workspace and
+        Project model elements as if they were "events", by encapsulating
+        them into an EntityRunEvent. It is up to the actors to make sense
+        of why the entity is an event.
     """
             
     def __init__(self, run):
@@ -244,9 +259,8 @@
         
 class EntityRunEvent(RunEvent):
     """
-    
-        An event to actors (e.g. a project built, a module updated)
-        
+        An event to actors (e.g. a project built, a module updated) that is
+        associated with a particular piece of the gump model.
     """
             
     def __init__(self, run, entity, realtime=0):
@@ -261,15 +275,13 @@
     def getEntity(self):
         return self.entity 
         
-    def isRealtime(self):
+    def isRealtime(self): #TODO: what is "realtime"?
         return self.realtime    
         
                 
 class RunRequest(RunEvent):
     """
-    
         A request for some work (not used yet)
-
     """            
     def __init__(self, run, type):
         RunEvent.__init__(self,run)
@@ -284,10 +296,8 @@
         
 class EntityRunRequest(RunEvent):
     """
-    
         An request regarding a known entity (e.g. Workspace/Module/Project).
         (not used yet)
-        
     """
     def __init__(self, run, type, entity):
         RunEvent.__init__(self, run, type)

Modified: gump/trunk/python/gump/core/runner/__init__.py
Url: http://svn.apache.org/viewcvs/gump/trunk/python/gump/core/runner/__init__.py?view=diff&rev=123529&p1=gump/trunk/python/gump/core/runner/__init__.py&r1=123528&p2=gump/trunk/python/gump/core/runner/__init__.py&r2=123529
==============================================================================
--- gump/trunk/python/gump/core/runner/__init__.py	(original)
+++ gump/trunk/python/gump/core/runner/__init__.py	Tue Dec 28 10:30:14 2004
@@ -1,6 +1,5 @@
 #!/usr/bin/env python
-
-#!/usr/bin/env python
+#
 # Copyright 2003-2004 The Apache Software Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +14,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# tell Python what modules make up the gump.test package
-__all__ = ["runner","demand","tasks"]
+# tell Python what modules make up the gump.runner package
+__all__ = ["runner","demand"]
+
+"""
+The gump.runner module contains the "main application loop" for a gump run.
+This is the place where threads are spawned, the project build list is
+iterated over, etcetera. Responsibility is split between the abstract
+GumpRunner class (which does basic setup) and subclasses that customize
+behaviour like multithreading and/or which actors are run.
 
-    
+Which runner to use is determined using the gump.runner.getRunner() method.
+"""
\ No newline at end of file

Modified: gump/trunk/python/gump/core/runner/demand.py
Url: http://svn.apache.org/viewcvs/gump/trunk/python/gump/core/runner/demand.py?view=diff&rev=123529&p1=gump/trunk/python/gump/core/runner/demand.py&r1=123528&p2=gump/trunk/python/gump/core/runner/demand.py&r2=123529
==============================================================================
--- gump/trunk/python/gump/core/runner/demand.py	(original)
+++ gump/trunk/python/gump/core/runner/demand.py	Tue Dec 28 10:30:14 2004
@@ -15,17 +15,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""
-
-	The OnDemand runner performs a run, but does work on
-	modules as the needs of projects demands it.
-
-"""
-
 import os.path
 import sys
 
-from gump import log
 from gump.core.run.gumprun import *
 from gump.core.runner.runner import *
 from gump.core.config import dir, default, basicConfig
@@ -46,33 +38,21 @@
 
 from gump.util.threads.tools import *
 
-
-###############################################################################
-# Classes
-###############################################################################
-  
-class UpdateWork:
-    def __init__(self,runner,module):
-        self.runner=runner
-        self.module=module
-        
-    def __str__(self):
-        return 'UpdateWork:'+`self.module`
-        
-class UpdateWorker(WorkerThread):
-    def performWork(self,work):
-        # Do the work...
-        work.runner.performUpdate(work.module)
-        
 class OnDemandRunner(GumpRunner):
+    """
+	The OnDemand runner updates modules just-in-time before a project is built.
+	
+	However, if gump is configured for multithreading, it also spawns several updater
+	threads in the background which do module updates. This is an effort to maximize
+	network and disk I/O.
+    """
 
-    def __init__(self,run):
-        GumpRunner.__init__(self,run)
+    def __init__(self, run, log=None):
+        GumpRunner.__init__(self,run,log)
 
-    ###########################################
     def spawnUpdateThreads(self, updaters=1):
         """
-        Fork off a bunch of threads.
+        Fork off a bunch of threads for running module updates.
         """
         
         self.workList=ThreadWorkList('Updates')
@@ -93,14 +73,14 @@
         
     def performUpdate(self,module):
         """
-        
-        	Perform a module update (locking whilst doing it)	
+        	Perform the (cvs,svn) update of a single module.
         	
+        	The module is locked during the update. Most of the actual work
+        	is delegated to the updater that's provided by the parent GumpRunner
+        	class.
         """
         
-        # Lock the module, while we work on it...
         lock=module.getLock()
-        
         try:
             lock.acquire()
         
@@ -122,7 +102,10 @@
             
     def performBuild(self,project):
         """
-            Perform a project build
+            Perform the actual (ant,maven,make) build of a single project.
+            
+            Most of the actual work is delegated to the builder that's
+            provided by the parent GumpRunner class.
         """
             
         # Perform the build action
@@ -134,11 +117,8 @@
         # Mark completed
         self.run.getGumpSet().setCompletedProject(project)
         
-    ###########################################
-
     def performRun(self):
         """
-        
         	Perform a run, building projects (and updating modules)
         	as needed.
         	
@@ -149,6 +129,9 @@
         	Fire events (1) before everything (2) for each entity
         	[module or project] and (3) after everything.
         	
+        	You may think of this method as performing "all the real beef" for
+        	a gump run, delegating to lots of different helpers and actors in
+        	the process.
         """
         # Initialize to run
         self.initialize(True)
@@ -189,7 +172,7 @@
             if gumpOptions.isUpdate():
                 # W/ multiple project in one module, it may be done
                 if not module.isUpdated():
-                    log.debug('Update module *inlined* (not in background thread) ' + `module`
+ '.')     
+                    self.log.debug('Update module *inlined* (not in background thread) '
+ `module` + '.')     
                     inlined+=1
                     self.performUpdate(module)
 
@@ -223,3 +206,24 @@
             result = EXIT_CODE_FAILED
             
         return result  
+
+class UpdateWork:
+    """
+    Simple internal helper class which defines a unit of module updating work that can be
+    handled by one of the update workers.
+    """
+    def __init__(self,runner,module):
+        self.runner=runner
+        self.module=module
+        
+    def __str__(self):
+        return 'UpdateWork:'+`self.module`
+        
+class UpdateWorker(WorkerThread):
+    """
+    Simple internal worker thread which performs one unit of module updating work (one
+    UpdateWork) each time it is fired up.
+    """
+    def performWork(self,work):
+        # Do the work...
+        work.runner.performUpdate(work.module)

Modified: gump/trunk/python/gump/core/runner/runner.py
Url: http://svn.apache.org/viewcvs/gump/trunk/python/gump/core/runner/runner.py?view=diff&rev=123529&p1=gump/trunk/python/gump/core/runner/runner.py&r1=123528&p2=gump/trunk/python/gump/core/runner/runner.py&r2=123529
==============================================================================
--- gump/trunk/python/gump/core/runner/runner.py	(original)
+++ gump/trunk/python/gump/core/runner/runner.py	Tue Dec 28 10:30:14 2004
@@ -15,15 +15,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""
-
-"""
-
 import os.path
 import sys
 
-from gump import log
-
 from gump.core.update.updater import *
 from gump.core.build.builder import *
 
@@ -41,43 +35,57 @@
 from gump.actor.results.resulter import Resulter
 from gump.actor.syndication.syndicator import Syndicator
 
-###############################################################################
-# Classes
-###############################################################################
-
-
 class GumpRunner(RunSpecific):
+    """
+    Base class for other runners that initializes several helper objects.
+    
+    the lifecycle for this class is as follows:
+    
+        runner.initialize() # set up environment
+        runner.perform()    # delegates to subclass to perform actual work
+        runner.finalize()   # do some cleanup work
+    """
 
-    def __init__(self, run):
-        
-        #
+    def __init__(self, run, log=None):
         RunSpecific.__init__(self, run)
         
-        # Main players (soon we ought make
-        # them into actors, like the others).         
-        self.updater=GumpUpdater(run)
-        self.builder=GumpBuilder(run)
+        if not log: from gump import log
+        self.log = log
         
+        # Main players (soon we ought make them into actors, like the others).         
+        self.updater = GumpUpdater(run)
+        self.builder = GumpBuilder(run)
         
         # A helper per language/type
-        self.java=gump.core.language.java.JavaHelper(run)
-        self.csharp=gump.core.language.csharp.CSharpHelper(run)
+        self.java = gump.core.language.java.JavaHelper(run)
+        self.csharp = gump.core.language.csharp.CSharpHelper(run)
         
         # Stash them for reference...
         run.setUpdater(self.updater)
-        run.setBuilder(self.builder)    
+        run.setBuilder(self.builder)
             
         run.addLanguageHelper(Project.JAVA_LANGUAGE,self.java)  
         run.addLanguageHelper(Project.CSHARP_LANGUAGE,self.csharp)
         
     def initialize(self,exitOnError=True):
+        """
+        Set up all of the neccessary resources for the subclass implementation to use.
+        Besides modifying the properties of this class, we also modify bits of the
+        workspace and bits of the GumpRun instance.
+        
+        TODO: currently this method must be called from the performRun() method of the
+        subclass. Call it from perform() instead.
+        
+        TODO: clean this up and have a clear responsibility split between the various
+        parts we're modifying here...
+        """
         
         logResourceUtilization('Before initialize')
         
         # Perform start-up logic 
         workspace = self.run.getWorkspace()
                 
-        #Check out environment
+        # Check out environment
         if not self.run.getOptions().isQuick():
             logResourceUtilization('Before check environment')            
             self.run.getEnvironment().checkEnvironment(exitOnError)
@@ -94,13 +102,12 @@
         if not workspace.getVersion() >= setting.WS_VERSION:
             message='Workspace version ['+str(workspace.getVersion())+'] below preferred
[' + setting.WS_VERSION + ']'
             workspace.addWarning(message)
-            log.warn(message)   
-            
-        # Check the workspace
+            self.log.warn(message)   
+
         if not workspace.getVersion() >= setting.WS_MINIMUM_VERSION:
             message='Workspace version ['+str(workspace.getVersion())+'] below minimum ['
+ setting.WS_MINIMUM_VERSION + ']'
             workspace.addError(message)
-            log.error(message)   
+            self.log.error(message)   
             
         # Write workspace to a 'merge' file        
         if not self.run.getOptions().isQuick():
@@ -118,7 +125,13 @@
     
     def initializeActors(self):
         """
-        Install the appropriate actors..
+        Populate the GumpRun instance with the various actors.
+        
+        The actors handle all the "optional" behaviour like writing HTML or sending e-mail.
One
+        way to think of this method is where we configure the "glue" between all the different
+        bits and pieces of the application.
+        
+        TODO:
         """
         
         # Stamp times
@@ -141,7 +154,7 @@
                 import gump.actor.mysql.databaser
                 self.run.registerActor(gump.actor.mysql.databaser.Databaser(self.run))
             except Exception, details:
-                log.warning('Unable to register Database Actor :  %s ' % details,
+                self.log.warning('Unable to register Database Actor :  %s ' % details,
                             exc_info=1)
         
         # Add Historical Database storer -- ??? no such thing...
@@ -152,7 +165,7 @@
                 import gump.actor.history.historical
                 self.run.registerActor(gump.actor.history.historical.Historical(self.run))
             except Exception, details:
-                log.warning('Unable to register Historical Database Actor :  %s ' % details,
+                self.log.warning('Unable to register Historical Database Actor :  %s ' %
details,
                             exc_info=1)
 
         # Add Dynagump database populator
@@ -190,7 +203,7 @@
                 import gump.actor.rdf.describer
                 self.run.registerActor(gump.actor.rdf.describer.RDFDescriber(self.run)) 
 
             except Exception, details:
-                log.warning('Unable to register RDF Describer :  %s ' % details,
+                self.log.warning('Unable to register RDF Describer :  %s ' % details,
                             exc_info=1)
             
         # Publish artifacts
@@ -219,10 +232,10 @@
     def getBuilder(self):
         return self.builder
    
-    #
-    # Call a method called 'documentRun(run)'
-    #
     def perform(self):
+        """
+        Does the actual gump work by delegating to the performRun(run) method of a subclass.
+        """
         if not hasattr(self,'performRun'):
             raise RuntimeError, \
                     'Class [' + `self.__class__` + '] needs a performRun(self,run)'
@@ -231,10 +244,13 @@
             raise RuntimeError, \
                     'Class [' + `self.__class__` + '] needs a callable performRun(self,run)'
         
-        log.debug('Perform run using [' + `self` + ']')
+        self.log.debug('Perform run using [' + `self` + ']')
         
         return self.performRun()
 
 def getRunner(run):
+    """
+    Factory method that provides the default GumpRunner subclass to use.
+    """
     from gump.core.runner.demand import OnDemandRunner
     return OnDemandRunner(run)

Mime
View raw message