From 4079b7111eea83f5f02f42712ca93ce40897a30f Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 27 May 2008 23:10:45 +0200 Subject: [PATCH] Added experiemental support for max-sockets for Z39.50 client. Added experiemental support for max-sockets for Z39.50 client. The max-sockets is by default disabled. Is enabled by having a max-sockets element in configuration. If max-sockets is reached a client waits a certain time before giving up (currently 15 seconds). --- src/filter_z3950_client.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/filter_z3950_client.cpp b/src/filter_z3950_client.cpp index 485c419..d0d0442 100644 --- a/src/filter_z3950_client.cpp +++ b/src/filter_z3950_client.cpp @@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include +#include #include #include @@ -76,6 +77,7 @@ namespace metaproxy_1 { public: // number of seconds to wait before we give up request int m_timeout_sec; + int m_max_sockets; std::string m_default_target; std::string m_force_target; boost::mutex m_mutex; @@ -181,6 +183,7 @@ yazpp_1::IPDU_Observer *yf::Z3950Client::Assoc::sessionNotify( yf::Z3950Client::Z3950Client() : m_p(new yf::Z3950Client::Rep) { m_p->m_timeout_sec = 30; + m_p->m_max_sockets = 0; } yf::Z3950Client::~Z3950Client() { @@ -279,6 +282,7 @@ yf::Z3950Client::Assoc *yf::Z3950Client::Rep::get_assoc(Package &package) return 0; } } + std::list dblist; std::string host; mp::util::split_zurl(target, host, dblist); @@ -288,6 +292,33 @@ yf::Z3950Client::Assoc *yf::Z3950Client::Rep::get_assoc(Package &package) ; // z3950_client: Databases in vhost ignored } + while (m_max_sockets) + { + int number = 0; + it = m_clients.begin(); + for (; it != m_clients.end(); it++) + { + yf::Z3950Client::Assoc *as = it->second; + if (!strcmp(as->get_hostname(), host.c_str())) + number++; + } + if (number < m_max_sockets) + break; + boost::xtime xt; + xtime_get(&xt, boost::TIME_UTC); + + xt.sec += 15; + if (!m_cond_session_ready.timed_wait(lock, xt)) + { + mp::odr odr; + + package.response() = odr.create_initResponse( + apdu, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, "max sessions"); + package.session().close(); + return 0; + } + } + yazpp_1::SocketManager *sm = new yazpp_1::SocketManager; yazpp_1::PDU_Assoc *pdu_as = new yazpp_1::PDU_Assoc(sm); yf::Z3950Client::Assoc *as = new yf::Z3950Client::Assoc(sm, pdu_as, @@ -370,7 +401,7 @@ void yf::Z3950Client::Rep::release_assoc(Package &package) // wait until no one is waiting for it. while (it->second->m_queue_len) m_cond_session_ready.wait(lock); - + // the Z_Assoc and PDU_Assoc must be destroyed before // the socket manager.. so pull that out.. first.. yazpp_1::SocketManager *s = it->second->m_socket_manager; @@ -410,6 +441,10 @@ void yf::Z3950Client::configure(const xmlNode *ptr, bool test_only) { m_p->m_force_target = mp::xml::get_text(ptr); } + else if (!strcmp((const char *) ptr->name, "max-sockets")) + { + m_p->m_max_sockets = mp::xml::get_int(ptr->children, 0); + } else { throw mp::filter::FilterException("Bad element " -- 1.7.10.4