Fix load_balance: does not retry dead target MP-626
[metaproxy-moved-to-github.git] / src / filter_load_balance.cpp
index 6a09ef3..1ad761c 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of Metaproxy.
-   Copyright (C) 2005-2009 Index Data
+   Copyright (C) Index Data
 
 Metaproxy is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -17,11 +17,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
 #include "config.hpp"
-#include "session.hpp"
-#include "package.hpp"
-#include "filter.hpp"
+#include <metaproxy/package.hpp>
+#include <metaproxy/filter.hpp>
 #include "filter_load_balance.hpp"
-#include "util.hpp"
+#include <metaproxy/util.hpp>
 
 
 #include <boost/thread/mutex.hpp>
@@ -35,7 +34,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #undef max
 #endif
 
-//#include <iostream>
 #include <list>
 #include <map>
 #include <limits>
@@ -55,7 +53,7 @@ namespace metaproxy_1
             void process(metaproxy_1::Package & package);
             void configure(const xmlNode * ptr);
         private:
-            // statistic manipulating functions, 
+            // statistic manipulating functions,
             void add_dead(unsigned long session_id);
             //void clear_dead(unsigned long session_id);
             void add_package(unsigned long session_id);
@@ -89,7 +87,7 @@ namespace metaproxy_1
 }
 
 // define Pimpl wrapper forwarding to Impl
+
 yf::LoadBalance::LoadBalance() : m_p(new Impl)
 {
 }
@@ -98,7 +96,8 @@ yf::LoadBalance::~LoadBalance()
 {  // must have a destructor because of boost::scoped_ptr
 }
 
-void yf::LoadBalance::configure(const xmlNode *xmlnode, bool test_only)
+void yf::LoadBalance::configure(const xmlNode *xmlnode, bool test_only,
+                                const char *path)
 {
     m_p->configure(xmlnode);
 }
@@ -114,7 +113,7 @@ yf::LoadBalance::Impl::Impl()
 }
 
 yf::LoadBalance::Impl::~Impl()
-{ 
+{
 }
 
 void yf::LoadBalance::Impl::configure(const xmlNode *xmlnode)
@@ -124,12 +123,12 @@ void yf::LoadBalance::Impl::configure(const xmlNode *xmlnode)
 void yf::LoadBalance::Impl::process(mp::Package &package)
 {
     bool is_closed_front = false;
-    
+
     // checking for closed front end packages
     if (package.session().is_closed())
     {
         is_closed_front = true;
-    }    
+    }
 
     Z_GDU *gdu_req = package.request().get();
 
@@ -151,52 +150,48 @@ void yf::LoadBalance::Impl::process(mp::Package &package)
             // they turn out to be bad..
             while (1)
             {
-                std::string target;
                 std::list<std::string>::iterator ivh = vhosts.begin();
+                std::list<std::string>::iterator ivh_pick = vhosts.end();
 
                 Package init_pkg(package.session(), package.origin());
                 init_pkg.copy_filter(package);
 
                 unsigned int cost = std::numeric_limits<unsigned int>::max();
-                { 
+                {
                     boost::mutex::scoped_lock scoped_lock(m_mutex);
-                    
-                    for (; ivh != vhosts.end(); )
+
+                    for (; ivh != vhosts.end(); ivh++)
                     {
                         if ((*ivh).size() != 0)
                         {
-                            unsigned int vhcost 
+                            unsigned int vhcost
                                 = yf::LoadBalance::Impl::cost(*ivh);
                             yaz_log(YLOG_LOG, "Consider %s cost=%u vhcost=%u",
                                     (*ivh).c_str(), cost, vhcost);
                             if (cost > vhcost)
                             {
+                                ivh_pick = ivh;
                                 cost = vhcost;
-                                target = *ivh;
-                                ivh = vhosts.erase(ivh);
                             }
-                            else
-                                ivh++;
                         }
-                        else
-                            ivh++;
                     }
                 }
-                if (target.length() == 0)
+                if (ivh_pick == vhosts.end())
                     break;
+                std::string target = *ivh_pick;
+                vhosts.erase(ivh_pick);
                 // copying new target into init package
-                
                 yazpp_1::GDU init_gdu(base_req);
                 Z_InitRequest *init_req = init_gdu.get()->u.z3950->u.initRequest;
-                
-                mp::util::set_vhost_otherinfo(&(init_req->otherInfo), 
+
+                mp::util::set_vhost_otherinfo(&(init_req->otherInfo),
                                               odr_en, target, 1);
-                
+
                 init_pkg.request() = init_gdu;
-                
-                // moving all package types 
+
+                // moving all package types
                 init_pkg.move();
-                
+
                 // checking for closed back end packages
                 if (!init_pkg.session().is_closed())
                 {
@@ -217,18 +212,18 @@ void yf::LoadBalance::Impl::process(mp::Package &package)
         else if (gdu_req->u.z3950->which == Z_APDU_close)
         {
             is_closed_front = true;
-            boost::mutex::scoped_lock scoped_lock(m_mutex);        
+            boost::mutex::scoped_lock scoped_lock(m_mutex);
             add_package(package.session().id());
-        }    
+        }
         // any other Z39.50 package is added to statistics
         else
         {
-            boost::mutex::scoped_lock scoped_lock(m_mutex);        
+            boost::mutex::scoped_lock scoped_lock(m_mutex);
             add_package(package.session().id());
         }
     }
 
-    // moving all package types 
+    // moving all package types
     package.move();
 
     bool is_closed_back = false;
@@ -248,7 +243,7 @@ void yf::LoadBalance::Impl::process(mp::Package &package)
             is_closed_back = true;
             boost::mutex::scoped_lock scoped_lock(m_mutex);
             remove_package(package.session().id());
-        } 
+        }
         // any other Z39.50 package is removed from statistics
         else
         {
@@ -262,7 +257,7 @@ void yf::LoadBalance::Impl::process(mp::Package &package)
     {
         boost::mutex::scoped_lock scoped_lock(m_mutex);
 
-        // marking backend dead if backend closed without fronted close 
+        // marking backend dead if backend closed without fronted close
         if (is_closed_front == false)
             add_dead(package.session().id());
 
@@ -272,21 +267,21 @@ void yf::LoadBalance::Impl::process(mp::Package &package)
         package.session().close();
     }
 }
-            
-// statistic manipulating functions, 
+
+// statistic manipulating functions,
 void yf::LoadBalance::Impl::add_dead(unsigned long session_id)
 {
     std::string target = find_session_target(session_id);
 
     if (target.size() != 0)
     {
-        std::map<std::string, TargetStat>::iterator itarg;        
+        std::map<std::string, TargetStat>::iterator itarg;
         itarg = m_target_stat.find(target);
         if (itarg != m_target_stat.end()
             && itarg->second.deads < std::numeric_limits<unsigned int>::max())
         {
             itarg->second.deads += 1;
-            // std:.cout << "add_dead " << session_id << " " << target 
+            // std:.cout << "add_dead " << session_id << " " << target
             //          << " d:" << itarg->second.deads << "\n";
         }
     }
@@ -298,10 +293,10 @@ void yf::LoadBalance::Impl::add_package(unsigned long session_id)
 
     if (target.size() != 0)
     {
-        std::map<std::string, TargetStat>::iterator itarg;        
+        std::map<std::string, TargetStat>::iterator itarg;
         itarg = m_target_stat.find(target);
         if (itarg != m_target_stat.end()
-            && itarg->second.packages 
+            && itarg->second.packages
                < std::numeric_limits<unsigned int>::max())
         {
             itarg->second.packages += 1;
@@ -315,7 +310,7 @@ void yf::LoadBalance::Impl::remove_package(unsigned long session_id)
 
     if (target.size() != 0)
     {
-        std::map<std::string, TargetStat>::iterator itarg;        
+        std::map<std::string, TargetStat>::iterator itarg;
         itarg = m_target_stat.find(target);
         if (itarg != m_target_stat.end()
             && itarg->second.packages > 0)
@@ -325,7 +320,7 @@ void yf::LoadBalance::Impl::remove_package(unsigned long session_id)
     }
 }
 
-void yf::LoadBalance::Impl::add_session(unsigned long session_id, 
+void yf::LoadBalance::Impl::add_session(unsigned long session_id,
                                         std::string target)
 {
     // finding and adding session
@@ -346,7 +341,7 @@ void yf::LoadBalance::Impl::add_session(unsigned long session_id,
         stat.packages = 0;
         stat.deads = 0;
         m_target_stat.insert(std::make_pair(target, stat));
-    } 
+    }
     else if (itarg->second.sessions < std::numeric_limits<unsigned int>::max())
     {
         itarg->second.sessions += 1;
@@ -373,7 +368,7 @@ void yf::LoadBalance::Impl::remove_session(unsigned long session_id)
         m_session_target.erase(isess);
         return;
     }
-    
+
     // counting session down
     if (itarg->second.sessions > 0)
         itarg->second.sessions -= 1;
@@ -403,7 +398,7 @@ unsigned int yf::LoadBalance::Impl::cost(std::string target)
 
     if (target.size() != 0)
     {
-        std::map<std::string, TargetStat>::iterator itarg;        
+        std::map<std::string, TargetStat>::iterator itarg;
         itarg = m_target_stat.find(target);
         if (itarg != m_target_stat.end())
             cost = itarg->second.cost();
@@ -417,7 +412,7 @@ unsigned int yf::LoadBalance::Impl::dead(std::string target)
 
     if (target.size() != 0)
     {
-        std::map<std::string, TargetStat>::iterator itarg;        
+        std::map<std::string, TargetStat>::iterator itarg;
         itarg = m_target_stat.find(target);
         if (itarg != m_target_stat.end())
             dead = itarg->second.deads;