Example #1
0
  def test_task_manager_stop_on_fail(self):
    tm = TaskManager( 4, stop_on_fail = True )
    
    results = set()
    
    num_tasks = 8
    
    for i in range(3):
      tm.addTask( i, _doAppend, i, results, 0.3 )
    
    tm.addTask( i + 1, _doFail, 0.1 )
    
    for i in range(i + 2,num_tasks):
      tm.addTask( i, _doAppend, i, results, 0 )
    
    time.sleep(1)
    
    done_tasks = sorted( tm.finishedTasks(), key=lambda t: t.task_id )
    self.assertEqual( len(done_tasks), 4 )
    
    expected_tasks = [ TaskResult( task_id, error, result ) \
                       for task_id, error, result in zip(range(4), [None] * num_tasks, [None] * num_tasks ) ] 

    self.assertEqual( done_tasks[:3], expected_tasks[:3] )
    
    self.assertEqual( done_tasks[3].task_id, 3 )
    self.assertIsNotNone( done_tasks[3].error )
Example #2
0
 def test_task_manager_one_fail(self):
   tm = TaskManager( 4 )
   
   results = set()
   
   num_tasks = 3
   
   tm.addTask( 0, _doAppend, 0, results, 0.3 )
   
   tm.addTask( 1, _doFail, 0.1 )
   
   tm.addTask( 2, _doAppend, 2, results, 0 )
   
   time.sleep(1)
   
   done_tasks = sorted( tm.finishedTasks(), key= lambda v: v.task_id )
   self.assertEqual( len(done_tasks), num_tasks )
   
   expected_tasks = [ TaskResult( task_id, error, result ) \
                      for task_id, error, result in zip(range(num_tasks), [None] * num_tasks, [None] * num_tasks ) ] 
   
   self.assertEqual( done_tasks[0], expected_tasks[0] )
   
   self.assertEqual( done_tasks[1].task_id, 1 )
   self.assertIsNotNone( done_tasks[1].error )
   
   self.assertEqual( done_tasks[2], expected_tasks[2] )
Example #3
0
 def test_task_manager_fail(self):
   tm = TaskManager( num_threads = 4 )
   
   num_of_tasks = 100
   
   for i in range(num_of_tasks):
     tm.addTask( i, _doFail, 0.0 )
   
   time.sleep(1) # wait until all tasks are done
   
   done_tasks = tm.finishedTasks()
   
   self.assertEqual( len(done_tasks), num_of_tasks )
   
   for i, t in enumerate( sorted(done_tasks) ):
     self.assertEqual( t.task_id, i )
     self.assertIsNotNone( t.error )
Example #4
0
 def test_task_manager(self):
   tm = TaskManager( 4 )
   
   results = set()
   
   num_of_tasks = 8
   
   for i in range(0,num_of_tasks):
     tm.addTask( i, _doAppend, i, results )
   
   time.sleep(0.5) # wait until all tasks are done
   
   done_tasks = tm.finishedTasks()
   expected_tasks = [ TaskResult( task_id ) for task_id in range(num_of_tasks) ]
   
   self.assertEqual( sorted(expected_tasks), expected_tasks )
   self.assertEqual( results, set(range(num_of_tasks)) )
Example #5
0
 def test_task_manager_finish(self):
   tm = TaskManager( 1 )
   
   results = set()
   
   num_tasks = 8
   
   for i in range(num_tasks):
     tm.addTask( i, _doAppend, i, results, 0.2 )
   
   tm.finish()
   
   for i in range(num_tasks, num_tasks * 2):
     tm.addTask( i, _doAppend, i, results, 0.2 )
   
   self.assertEqual( results, set(range(num_tasks)) )
   
   done_tasks = tm.finishedTasks()
   expected_tasks = [ TaskResult( task_id ) for task_id in range(num_tasks) ] 
   
   self.assertEqual( sorted(done_tasks), expected_tasks )
Example #6
0
 def test_task_manager_stop(self):
   
   jobs = 4
   num_tasks = 8
   
   tm = TaskManager( num_threads = jobs )
   
   results = set()
   
   for i in range(num_tasks):
     tm.addTask( i, _doAppend, i, results, 1 )
   
   time.sleep(0.2)
   
   tm.stop()
   tm.stop()
   
   done_tasks = sorted( tm.finishedTasks(), key = lambda result: result.task_id )
   
   expected_tasks = [ TaskResult( task_id ) for task_id in range(jobs) ]
   
   self.assertEqual( sorted(done_tasks), expected_tasks )
   self.assertEqual( results, set(range(jobs)) )
Example #7
0
class _NodesBuilder (object):
  
  __slots__ = \
  (
    'vfiles',
    'build_manager',
    'task_manager',
    'node_states',
    'building_nodes',
  )
  
  #//-------------------------------------------------------//
  
  def   __init__( self, build_manager, jobs = 0, keep_going = False, with_backtrace = True ):
    self.vfiles         = _VFiles()
    self.node_states    = {}
    self.building_nodes = {}
    self.build_manager  = build_manager
    self.task_manager   = TaskManager( num_threads = jobs, stop_on_fail = not keep_going, with_backtrace = with_backtrace )
  
  #//-------------------------------------------------------//
  
  def   __enter__(self):
    return self
  
  #//-------------------------------------------------------//
  
  def   __exit__(self, exc_type, exc_value, backtrace):
    self.close()
  
  #//-------------------------------------------------------//
  
  def   _getNodeState( self, node ):
    try:
      state = self.node_states[ node ]
    except KeyError:
      state = _NodeState()
      self.node_states[ node ] = state
    
    return state
  
  #//-------------------------------------------------------//
  
  def   _removeNodeState( self, node ):
    try:
      del self.node_states[ node ]
    except KeyError:
      pass
  
  #//-------------------------------------------------------//
  
  def   _addBuildingNode( self, node, state ):
    conflicting_nodes = []
    building_nodes = self.building_nodes
    
    for name, signature in node.getNamesAndSignatures():
      node_signature = (node, signature)
      
      other_node, other_signature = building_nodes.setdefault( name, node_signature )
      if other_node is not node:
        if other_signature != signature:
          raise ErrorNodeSignatureDifferent( node )
        
        conflicting_nodes.append( other_node )
    
    if conflicting_nodes:
      state.check_actual = True
      self.build_manager.depends( node, conflicting_nodes )
      return True
    
    return False
  
  #//-------------------------------------------------------//
  
  def   _removeBuildingNode( self, node ):
    building_nodes = self.building_nodes
    for name in node.getNames():
      del building_nodes[ name ]
  
  #//-------------------------------------------------------//
  
  def   isBuilding(self):
    return bool(self.building_nodes)
  
  #//-------------------------------------------------------//
  
  def   _checkPrebuildDepends( self, node ):
    dep_nodes = node.buildDepends()
    if dep_nodes:
      self.build_manager.depends( node, dep_nodes )
      return True
    
    return False
  
  #//-------------------------------------------------------//
  
  def _checkPrebuildReplace( self, node ):
    
    if node.buildReplace():
      new_node_sources = node.getSourceNodes()
      if new_node_sources:
        self.build_manager.depends( node, new_node_sources )
        return True
    
    return False
  
  #//-------------------------------------------------------//
  
  def   _checkPrebuildSplit( self, node, state ):
    
    build_manager = self.build_manager
    
    if state.check_split:
      state.check_split = False
      
      check_actual = True
      
      if node.isBatch() and state.check_actual:
        # Check for changed sources of BatchNode
        vfile = self.vfiles[ node.builder ]
        actual = build_manager.isActualNode( node, vfile )
        
        if actual:
          self._removeNodeState( node )
          build_manager.actualNode( node )
          return True
        
        check_actual = False
      
      split_nodes = node.buildSplit()
      if split_nodes:
        state.split_nodes = split_nodes
        for split_node in split_nodes:
          split_state = self._getNodeState( split_node )
          split_state.check_split = False
          split_state.check_depends = False
          split_state.check_replace = False
          split_state.check_actual = check_actual
          split_state.initialized = split_node.builder is node.builder
        
        self.build_manager.depends( node, split_nodes )
        return True
  
    elif state.split_nodes is not None:
      if node.isBatch():
        node._populateTargets()
      else:
        targets = []
        for split_node in state.split_nodes:
          targets += split_node.getTargetValues()
        
        node.target_values = targets
        
      self._removeNodeState( node )
      
      self.build_manager.completedSplitNode( node )
      
      return True
    
    return False
  
  #//-------------------------------------------------------//
  
  def   _prebuild( self, node, state ):
    
    # print( "node: %s, state: %s" % (node, state))
    
    if not state.initialized:
      node.initiate()
      state.initialized = True
    
    if state.check_depends:
      state.check_depends = False
      if self._checkPrebuildDepends( node ):
        return True
    
    if state.check_replace:
      state.check_replace = False
      if self._checkPrebuildReplace( node ):
        return True
    
    if self._checkPrebuildSplit( node, state ):
      return True
    
    return False
    
  #//-------------------------------------------------------//
  
  def   build( self, nodes ):
    
    build_manager = self.build_manager
    
    vfiles = self.vfiles
    addTask = self.task_manager.addTask
    
    tasks_check_period = 10
    added_tasks = 0
    changed = False
    
    for node in nodes:
      
      node_state = self._getNodeState( node )
      
      if self._prebuild( node, node_state ):
        changed = True
        continue
      
      if self._addBuildingNode( node, node_state ):
        continue
      
      if node_state.check_actual:
        vfile = vfiles[ node.builder ]
        actual = build_manager.isActualNode( node, vfile )
        
        if actual:
          self._removeNodeState( node )
          self._removeBuildingNode( node )
          build_manager.actualNode( node )
          changed = True
          continue
          
      addTask( node, _buildNode, node )
      
      added_tasks += 1
      
      if added_tasks == tasks_check_period:
        changed = self._getFinishedNodes( block = False ) or changed
        added_tasks = 0
    
    self._getFinishedNodes( block = not changed )
  
  #//-------------------------------------------------------//
  
  def   _getFinishedNodes( self, block = True ):
    # print("tasks: %s, finished_tasks: %s" % (self.task_manager.unfinished_tasks, self.task_manager.finished_tasks.qsize()))
    finished_tasks = self.task_manager.finishedTasks( block = block )
    
    vfiles = self.vfiles
    
    build_manager = self.build_manager
    
    for task in finished_tasks:
      node = task.task_id
      error = task.error
      
      self._removeNodeState( node )
      self._removeBuildingNode( node )
      
      vfile = vfiles[ node.builder ]
      
      if error is None:
        node.save( vfile )
        build_manager.completedNode( node, task.result )
      else:
        if node.isBatch():
          node.save( vfile )
        
        build_manager.failedNode( node, error )

    return bool(finished_tasks)
  
  #//-------------------------------------------------------//
  
  def   clear( self, nodes ):
    
    vfiles = self.vfiles
    build_manager = self.build_manager
    
    for node in nodes:
      
      node_state = self._getNodeState( node )
      
      node_state.check_actual = False
      
      if self._prebuild( node, node_state ):
        continue
      
      vfile = vfiles[ node.builder ]
      node.clear( vfile )
      build_manager.removedNode( node )
  
  #//-------------------------------------------------------//
  
  def   status( self, nodes ):
    
    vfiles = self.vfiles
    build_manager = self.build_manager
    
    for node in nodes:
      
      node_state = self._getNodeState( node )
      node_state.check_actual = False
      
      if self._prebuild( node, node_state ):
        continue
      
      vfile = vfiles[ node.builder ]
      if build_manager.isActualNode( node, vfile ):
        build_manager.actualNodeStatus( node )
      else:
        build_manager.outdatedNodeStatus( node )
  
  #//-------------------------------------------------------//
  
  def   close( self ):
    try:
      self.task_manager.stop()
      self._getFinishedNodes( block = False )
    finally:
      self.vfiles.close()