Salome HOME
Generate an error when no resource can run a task with the workload manager.
[modules/yacs.git] / src / workloadmanager / DefaultAlgorithm.cxx
index 96e48b4f65c5a645fa3a35a51112ada4c6466aa6..1b1896c26c301149d19c2c6c3c71ee2102bb2725 100644 (file)
@@ -60,37 +60,50 @@ WorkloadAlgorithm::LaunchInfo DefaultAlgorithm::chooseTask()
       itTask ++)
   {
     const ContainerType& ctype = (*itTask)->type();
-    std::list<ResourceLoadInfo>::iterator best_resource;
-    best_resource = _resources.end();
-    float best_cost = std::numeric_limits<float>::max();
-    bool isSupported = false;
-    for(auto itResource = _resources.begin();
-        itResource != _resources.end();
-        itResource++)
-      if(itResource->isSupported(ctype))
-      {
-        if(itResource->isAllocPossible(ctype))
+    if(ctype.ignoreResources)
+      result.taskFound = true;
+    else
+    {
+      std::list<ResourceLoadInfo>::iterator best_resource;
+      best_resource = _resources.end();
+      float best_cost = std::numeric_limits<float>::max();
+      bool isSupported = false;
+      for(auto itResource = _resources.begin();
+          itResource != _resources.end();
+          itResource++)
+        if(itResource->isSupported(ctype)
+            && (*itTask)->isAccepted(itResource->resource()))
         {
-          float thisCost = itResource->cost(ctype);
-          if( best_cost > thisCost)
+          isSupported = true;
+          if(itResource->isAllocPossible(ctype))
           {
-            best_cost = thisCost;
-            best_resource = itResource;
+            float thisCost = itResource->cost(ctype);
+            if( best_cost > thisCost)
+            {
+              best_cost = thisCost;
+              best_resource = itResource;
+            }
           }
         }
+      if(best_resource != _resources.end())
+      {
+        result.taskFound = true;
+        result.worker.resource = best_resource->resource();
+        result.worker.index = best_resource->alloc(ctype);
       }
-    if(best_resource != _resources.end())
+      else if(!isSupported && _resourcesFrozen)
+      {
+        // This task can never be run by any available resource.
+        result.taskFound = true;
+        result.worker.isOk = false;
+        result.worker.error_message = "No resource can run this task.";
+      }
+    }
+    if(result.taskFound)
     {
       chosenTaskIt = itTask;
       result.task = (*itTask);
-      result.taskFound = true;
-      result.worker.resource = best_resource->resource();
       result.worker.type = ctype;
-      result.worker.index = best_resource->alloc(ctype);
-    }
-    else if(!isSupported)
-    {
-      // TODO: This task can never be run by any available resource.
     }
   }
   if(result.taskFound)
@@ -100,13 +113,16 @@ WorkloadAlgorithm::LaunchInfo DefaultAlgorithm::chooseTask()
 
 void DefaultAlgorithm::liberate(const LaunchInfo& info)
 {
-  const Resource& r = info.worker.resource;
-  unsigned int index = info.worker.index;
   const ContainerType& ctype = info.worker.type;
-  std::list<ResourceLoadInfo>::iterator it = std::find(_resources.begin(),
-                                                       _resources.end(),
-                                                       r);
-  it->free(ctype, index); // we are sure to find it
+  if(!ctype.ignoreResources && info.worker.isOk)
+  {
+    const Resource& r = info.worker.resource;
+    unsigned int index = info.worker.index;
+    std::list<ResourceLoadInfo>::iterator it = std::find(_resources.begin(),
+                                                        _resources.end(),
+                                                        r);
+    it->free(ctype, index); // we are sure to find it
+  }
 }
 
 // ResourceInfoForContainer
@@ -158,6 +174,7 @@ bool DefaultAlgorithm::ResourceInfoForContainer::isContainerRunning
 DefaultAlgorithm::ResourceLoadInfo::ResourceLoadInfo(const Resource& r)
 : _resource(r)
 , _load(0.0)
+, _loadCost(0.0)
 , _ctypes()
 {
 }
@@ -167,7 +184,7 @@ bool DefaultAlgorithm::ResourceLoadInfo::isSupported
 {
   return ctype.neededCores <= _resource.nbCores ;
 }
-                                          
+
 bool DefaultAlgorithm::ResourceLoadInfo::isAllocPossible
                                 (const ContainerType& ctype)const
 {
@@ -177,7 +194,7 @@ bool DefaultAlgorithm::ResourceLoadInfo::isAllocPossible
 float DefaultAlgorithm::ResourceLoadInfo::cost
                                 (const ContainerType& ctype)const
 {
-  return _load * 100.0 / float(_resource.nbCores);
+  return _loadCost * 100.0 / float(_resource.nbCores);
 }
 
 unsigned int DefaultAlgorithm::ResourceLoadInfo::alloc
@@ -194,6 +211,10 @@ unsigned int DefaultAlgorithm::ResourceLoadInfo::alloc
     it--;
   }
   _load += ctype.neededCores;
+  if(ctype.neededCores == 0)
+    _loadCost += COST_FOR_0_CORE_TASKS;
+  else
+    _loadCost += ctype.neededCores;
   return it->alloc();
 }
 
@@ -201,6 +222,10 @@ void DefaultAlgorithm::ResourceLoadInfo::free
                                 (const ContainerType& ctype, int index)
 {
   _load -= ctype.neededCores;
+  if(ctype.neededCores == 0)
+    _loadCost -= COST_FOR_0_CORE_TASKS;
+  else
+    _loadCost -= ctype.neededCores;
   std::list<ResourceInfoForContainer>::iterator it = std::find(_ctypes.begin(),
                                                                _ctypes.end(),
                                                                ctype);