X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Ffilter_load_balance.cpp;h=e4ca3fbb3c481e5ff72c0d3f6d690b49f278123f;hb=fee3c45cf4ce01083218e41622f54e5fced0fadf;hp=1f31629f3400a1ab30f7df81d0534522fa85aa1a;hpb=4d075d6bf91d99f24e4434ce4807790f57d3fed1;p=metaproxy-moved-to-github.git diff --git a/src/filter_load_balance.cpp b/src/filter_load_balance.cpp index 1f31629..e4ca3fb 100644 --- a/src/filter_load_balance.cpp +++ b/src/filter_load_balance.cpp @@ -1,5 +1,5 @@ /* This file is part of Metaproxy. - Copyright (C) 2005-2009 Index Data + Copyright (C) 2005-2012 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,15 +17,16 @@ 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 +#include #include "filter_load_balance.hpp" -#include "util.hpp" +#include #include +#include +#include #include // remove max macro if already defined (defined later in ) @@ -33,7 +34,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #undef max #endif -//#include #include #include #include @@ -74,11 +74,6 @@ namespace metaproxy_1 unsigned int deads; unsigned int cost() { unsigned int c = sessions + packages + deads; - //std::cout << "stats c:" << c - // << " s:" << sessions - // << " p:" << packages - // << " d:" << deads - // <<"\n"; return c; } }; @@ -101,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); } @@ -126,10 +122,8 @@ void yf::LoadBalance::Impl::configure(const xmlNode *xmlnode) void yf::LoadBalance::Impl::process(mp::Package &package) { - bool is_closed_front = false; - bool is_closed_back = false; - + // checking for closed front end packages if (package.session().is_closed()) { @@ -144,53 +138,79 @@ void yf::LoadBalance::Impl::process(mp::Package &package) // target selecting only on Z39.50 init request if (gdu_req->u.z3950->which == Z_APDU_initRequest) { + yazpp_1::GDU base_req(gdu_req); + Z_APDU *apdu = base_req.get()->u.z3950; + + Z_InitRequest *org_init = base_req.get()->u.z3950->u.initRequest; mp::odr odr_en(ODR_ENCODE); - Z_InitRequest *org_init = gdu_req->u.z3950->u.initRequest; - // extracting virtual hosts std::list vhosts; - mp::util::remove_vhost_otherinfo(&(org_init->otherInfo), vhosts); - - // choosing one target according to load-balancing algorithm - - if (vhosts.size()) + // get lowest of all vhosts.. Remove them if individually if + // they turn out to be bad.. + while (1) { std::string target; + std::list::iterator ivh = vhosts.begin(); + + Package init_pkg(package.session(), package.origin()); + init_pkg.copy_filter(package); + unsigned int cost = std::numeric_limits::max(); - { //locking scope for local databases + { boost::mutex::scoped_lock scoped_lock(m_mutex); - // load-balancing algorithm goes here - //target = *vhosts.begin(); - for (std::list::const_iterator ivh - = vhosts.begin(); - ivh != vhosts.end(); - ivh++) + for (; ivh != vhosts.end(); ) { if ((*ivh).size() != 0) { 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) { cost = vhcost; target = *ivh; + ivh = vhosts.erase(ivh); } + else + ivh++; } - } - - // updating local database - add_session(package.session().id(), target); - yf::LoadBalance::Impl::cost(target); - add_package(package.session().id()); + else + ivh++; + } } - + if (target.length() == 0) + break; // copying new target into init package - mp::util::set_vhost_otherinfo(&(org_init->otherInfo), + + 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), odr_en, target, 1); - package.request() = gdu_req; + + init_pkg.request() = init_gdu; + + // moving all package types + init_pkg.move(); + + // checking for closed back end packages + if (!init_pkg.session().is_closed()) + { + add_session(package.session().id(), target); + + package.response() = init_pkg.response(); + return; + } } + mp::odr odr; + package.response() = odr.create_initResponse( + apdu, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, + "load_balance: no available targets"); + package.session().close(); + return; } // frontend Z39.50 close request is added to statistics and marked else if (gdu_req->u.z3950->which == Z_APDU_close) @@ -206,10 +226,12 @@ void yf::LoadBalance::Impl::process(mp::Package &package) add_package(package.session().id()); } } - + // moving all package types package.move(); + bool is_closed_back = false; + // checking for closed back end packages if (package.session().is_closed()) is_closed_back = true; @@ -269,10 +291,6 @@ void yf::LoadBalance::Impl::add_dead(unsigned long session_id) } } -//void yf::LoadBalance::Impl::clear_dead(unsigned long session_id){ -// std::cout << "clear_dead " << session_id << "\n"; -//}; - void yf::LoadBalance::Impl::add_package(unsigned long session_id) { std::string target = find_session_target(session_id); @@ -283,10 +301,9 @@ void yf::LoadBalance::Impl::add_package(unsigned long session_id) itarg = m_target_stat.find(target); if (itarg != m_target_stat.end() && itarg->second.packages - < std::numeric_limits::max()){ + < std::numeric_limits::max()) + { itarg->second.packages += 1; - // std:.cout << "add_package " << session_id << " " << target - // << " p:" << itarg->second.packages << "\n"; } } } @@ -303,8 +320,6 @@ void yf::LoadBalance::Impl::remove_package(unsigned long session_id) && itarg->second.packages > 0) { itarg->second.packages -= 1; - // std:.cout << "remove_package " << session_id << " " << target - // << " p:" << itarg->second.packages << "\n"; } } } @@ -327,17 +342,13 @@ void yf::LoadBalance::Impl::add_session(unsigned long session_id, { TargetStat stat; stat.sessions = 1; - stat.packages = 0; // no idea why the defaut constructor TargetStat() - stat.deads = 0; // is not initializig this correctly to zero ?? + stat.packages = 0; + stat.deads = 0; m_target_stat.insert(std::make_pair(target, stat)); - // std:.cout << "add_session " << session_id << " " << target - // << " s:1\n"; } else if (itarg->second.sessions < std::numeric_limits::max()) { itarg->second.sessions += 1; - // std:.cout << "add_session " << session_id << " " << target - // << " s:" << itarg->second.sessions << "\n"; } } @@ -366,11 +377,7 @@ void yf::LoadBalance::Impl::remove_session(unsigned long session_id) if (itarg->second.sessions > 0) itarg->second.sessions -= 1; - // std:.cout << "remove_session " << session_id << " " << target - // << " s:" << itarg->second.sessions << "\n"; - - // clearing empty sessions and targets - if (itarg->second.sessions == 0 && itarg->second.deads == 0 ) + if (itarg->second.sessions == 0 && itarg->second.deads == 0) { m_target_stat.erase(itarg); m_session_target.erase(isess); @@ -391,33 +398,29 @@ std::string yf::LoadBalance::Impl::find_session_target(unsigned long session_id) // cost functions unsigned int yf::LoadBalance::Impl::cost(std::string target) { - unsigned int cost; + unsigned int cost = 0; - if (target.size() != 0){ + if (target.size() != 0) + { std::map::iterator itarg; itarg = m_target_stat.find(target); - if (itarg != m_target_stat.end()){ + if (itarg != m_target_stat.end()) cost = itarg->second.cost(); - } } - - //std::cout << "cost " << target << " c:" << cost << "\n"; return cost; } unsigned int yf::LoadBalance::Impl::dead(std::string target) { - unsigned int dead; + unsigned int dead = 0; - if (target.size() != 0){ + if (target.size() != 0) + { std::map::iterator itarg; itarg = m_target_stat.find(target); - if (itarg != m_target_stat.end()){ + if (itarg != m_target_stat.end()) dead = itarg->second.deads; - } } - - //std::cout << "dead " << target << " d:" << dead << "\n"; return dead; }