X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;f=src%2Ffilter_session_shared.cpp;h=512c234b0801f477059abb6c2bf2d3ecdb994441;hb=637a685d61a9ff0e3f398a59da426979815c4d68;hp=e0f835b9dd42a76a24b5e6087210f641483a10c0;hpb=16921033f2609ed948cf6985b4fbce3d927a20c1;p=metaproxy-moved-to-github.git diff --git a/src/filter_session_shared.cpp b/src/filter_session_shared.cpp index e0f835b..512c234 100644 --- a/src/filter_session_shared.cpp +++ b/src/filter_session_shared.cpp @@ -1,7 +1,22 @@ -/* $Id: filter_session_shared.cpp,v 1.12 2006-06-19 23:54:02 adam Exp $ - Copyright (c) 2005-2006, Index Data. +/* $Id: filter_session_shared.cpp,v 1.18 2007-05-09 21:23:09 adam Exp $ + Copyright (c) 2005-2007, Index Data. - See the LICENSE file for details +This file is part of Metaproxy. + +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 +Software Foundation; either version 2, or (at your option) any later +version. + +Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Metaproxy; see the file LICENSE. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ #include "config.hpp" @@ -105,7 +120,10 @@ namespace metaproxy_1 { time_t m_backend_expiry_ttl; size_t m_backend_set_max; public: - BackendClass(const yazpp_1::GDU &init_request); + BackendClass(const yazpp_1::GDU &init_request, + int resultset_ttl, + int resultset_max, + int session_ttl); ~BackendClass(); }; class SessionShared::FrontendSet { @@ -124,9 +142,10 @@ namespace metaproxy_1 { ~Frontend(); bool m_is_virtual; bool m_in_use; - + Z_Options m_init_options; void search(Package &package, Z_APDU *apdu); void present(Package &package, Z_APDU *apdu); + void scan(Package &package, Z_APDU *apdu); void get_set(mp::Package &package, const Z_APDU *apdu_req, @@ -160,6 +179,9 @@ namespace metaproxy_1 { BackendClassMap m_backend_map; boost::mutex m_mutex_backend_map; boost::thread_group m_thrds; + int m_resultset_ttl; + int m_resultset_max; + int m_session_ttl; }; } } @@ -314,7 +336,25 @@ yf::SessionShared::BackendInstancePtr yf::SessionShared::BackendClass::create_ba init_package.copy_filter(frontend_package); - init_package.request() = m_init_request; + yazpp_1::GDU actual_init_request = m_init_request; + Z_GDU *init_pdu = actual_init_request.get(); + + assert(init_pdu->which == Z_GDU_Z3950); + assert(init_pdu->u.z3950->which == Z_APDU_initRequest); + + Z_InitRequest *req = init_pdu->u.z3950->u.initRequest; + ODR_MASK_ZERO(req->options); + + ODR_MASK_SET(req->options, Z_Options_search); + ODR_MASK_SET(req->options, Z_Options_present); + ODR_MASK_SET(req->options, Z_Options_namedResultSets); + ODR_MASK_SET(req->options, Z_Options_scan); + + ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1); + ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2); + ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3); + + init_package.request() = init_pdu; init_package.move(); @@ -350,10 +390,13 @@ yf::SessionShared::BackendInstancePtr yf::SessionShared::BackendClass::create_ba } -yf::SessionShared::BackendClass::BackendClass(const yazpp_1::GDU &init_request) +yf::SessionShared::BackendClass::BackendClass(const yazpp_1::GDU &init_request, + int resultset_ttl, + int resultset_max, + int session_ttl) : m_named_result_sets(false), m_init_request(init_request), - m_sequence_top(0), m_backend_set_ttl(30), - m_backend_expiry_ttl(90), m_backend_set_max(10) + m_sequence_top(0), m_backend_set_ttl(resultset_ttl), + m_backend_expiry_ttl(session_ttl), m_backend_set_max(resultset_max) {} yf::SessionShared::BackendClass::~BackendClass() @@ -365,6 +408,7 @@ void yf::SessionShared::Rep::init(mp::Package &package, const Z_GDU *gdu, Z_InitRequest *req = gdu->u.z3950->u.initRequest; frontend->m_is_virtual = true; + frontend->m_init_options = *req->options; InitKey k(req); { boost::mutex::scoped_lock lock(m_mutex_backend_map); @@ -372,7 +416,10 @@ void yf::SessionShared::Rep::init(mp::Package &package, const Z_GDU *gdu, it = m_backend_map.find(k); if (it == m_backend_map.end()) { - BackendClassPtr b(new BackendClass(gdu->u.z3950)); + BackendClassPtr b(new BackendClass(gdu->u.z3950, + m_resultset_ttl, + m_resultset_max, + m_session_ttl)); m_backend_map[k] = b; frontend->m_backend_class = b; std::cout << "SessionShared::Rep::init new session " @@ -399,10 +446,20 @@ void yf::SessionShared::Rep::init(mp::Package &package, const Z_GDU *gdu, else { boost::mutex::scoped_lock lock(bc->m_mutex_backend_class); - Z_GDU *response_gdu = bc->m_init_response.get(); + yazpp_1::GDU init_response = bc->m_init_response; + Z_GDU *response_gdu = init_response.get(); mp::util::transfer_referenceId(odr, gdu->u.z3950, response_gdu->u.z3950); - package.response() = response_gdu; + + Z_Options *server_options = + response_gdu->u.z3950->u.initResponse->options; + Z_Options *client_options = &frontend->m_init_options; + + int i; + for (i = 0; i<30; i++) + if (!ODR_MASK_GET(client_options, i)) + ODR_MASK_CLEAR(server_options, i); + package.response() = init_response; } if (backend) bc->release_backend(backend); @@ -424,7 +481,7 @@ yf::SessionShared::BackendSet::BackendSet( } bool yf::SessionShared::BackendSet::search( - Package &frontend_package, + mp::Package &frontend_package, const Z_APDU *frontend_apdu, const BackendInstancePtr bp) { @@ -488,18 +545,17 @@ bool yf::SessionShared::BackendSet::search( m_result_set_size = *b_resp->resultCount; return true; } + Z_APDU *f_apdu = 0; if (frontend_apdu->which == Z_APDU_searchRequest) - { - Z_APDU *f_apdu = - odr.create_searchResponse(frontend_apdu, 1, "Search closed"); - frontend_package.response() = f_apdu; - } - if (frontend_apdu->which == Z_APDU_presentRequest) - { - Z_APDU *f_apdu = - odr.create_presentResponse(frontend_apdu, 1, "Search closed"); - frontend_package.response() = f_apdu; - } + f_apdu = odr.create_searchResponse( + frontend_apdu, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0); + else if (frontend_apdu->which == Z_APDU_presentRequest) + f_apdu = odr.create_presentResponse( + frontend_apdu, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0); + else + f_apdu = odr.create_close( + frontend_apdu, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0); + frontend_package.response() = f_apdu; return false; } @@ -550,7 +606,6 @@ void yf::SessionShared::Frontend::override_set( return; } } - } void yf::SessionShared::Frontend::get_set(mp::Package &package, @@ -598,7 +653,29 @@ void yf::SessionShared::Frontend::get_set(mp::Package &package, { // create a new backend set (and new set) found_backend = bc->create_backend(package); - assert(found_backend); + + if (!found_backend) + { + Z_APDU *f_apdu = 0; + mp::odr odr; + if (apdu_req->which == Z_APDU_searchRequest) + { + f_apdu = odr.create_searchResponse( + apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0); + } + else if (apdu_req->which == Z_APDU_presentRequest) + { + f_apdu = odr.create_presentResponse( + apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0); + } + else + { + f_apdu = odr.create_close( + apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0); + } + package.response() = f_apdu; + return; + } std::cout << "NEW " << found_backend << "\n"; if (bc->m_named_result_sets) @@ -617,7 +694,7 @@ void yf::SessionShared::Frontend::get_set(mp::Package &package, if (!new_set->search(package, apdu_req, found_backend)) { std::cout << "search error\n"; - bc->release_backend(found_backend); + bc->remove_backend(found_backend); return; // search error } found_set = new_set; @@ -662,9 +739,9 @@ void yf::SessionShared::Frontend::search(mp::Package &package, BackendInstancePtr found_backend; // null get_set(package, apdu_req, databases, query, found_backend, found_set); - if (!found_set) return; + mp::odr odr; Z_APDU *f_apdu = odr.create_searchResponse(apdu_req, 0, 0); Z_SearchResponse *f_resp = f_apdu->u.searchResponse; @@ -746,11 +823,41 @@ void yf::SessionShared::Frontend::present(mp::Package &package, { bc->remove_backend(found_backend); Z_APDU *f_apdu_res = - odr.create_presentResponse(apdu_req, 1, "present error"); + odr.create_presentResponse( + apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0); package.response() = f_apdu_res; } } +void yf::SessionShared::Frontend::scan(mp::Package &frontend_package, + Z_APDU *apdu_req) +{ + BackendClassPtr bc = m_backend_class; + BackendInstancePtr backend = bc->get_backend(frontend_package); + if (!backend) + { + mp::odr odr; + Z_APDU *apdu = odr.create_scanResponse( + apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0); + frontend_package.response() = apdu; + } + else + { + Package scan_package(backend->m_session, frontend_package.origin()); + scan_package.copy_filter(frontend_package); + scan_package.request() = apdu_req; + scan_package.move(); + frontend_package.response() = scan_package.response(); + if (scan_package.session().is_closed()) + { + frontend_package.session().close(); + bc->remove_backend(backend); + } + else + bc->release_backend(backend); + } +} + yf::SessionShared::Worker::Worker(SessionShared::Rep *rep) : m_p(rep) { } @@ -770,12 +877,18 @@ void yf::SessionShared::BackendClass::expire() { std::cout << "expiry "; time_t last_use = (*bit)->m_time_last_use; - if ((now >= last_use && now - last_use > m_backend_expiry_ttl) + + if ((*bit)->m_in_use) + { + std::cout << "inuse"; + bit++; + } + else if ((now >= last_use && now - last_use > m_backend_expiry_ttl) || (now < last_use)) { mp::odr odr; (*bit)->m_close_package->response() = odr.create_close( - 0, Z_Close_lackOfActivity, "session expired"); + 0, Z_Close_lackOfActivity, 0); (*bit)->m_close_package->session().close(); (*bit)->m_close_package->move(); @@ -799,7 +912,7 @@ void yf::SessionShared::Rep::expire() boost::xtime_get(&xt, boost::TIME_UTC); xt.sec += 30; boost::thread::sleep(xt); - std::cout << "." << std::endl; + //std::cout << "." << std::endl; BackendClassMap::const_iterator b_it = m_backend_map.begin(); for (; b_it != m_backend_map.end(); b_it++) @@ -809,6 +922,9 @@ void yf::SessionShared::Rep::expire() yf::SessionShared::Rep::Rep() { + m_resultset_ttl = 30; + m_resultset_max = 10; + m_session_ttl = 90; yf::SessionShared::Worker w(this); m_thrds.add_thread(new boost::thread(w)); } @@ -919,6 +1035,10 @@ void yf::SessionShared::process(mp::Package &package) const { f->present(package, apdu); } + else if (apdu->which == Z_APDU_scanRequest) + { + f->scan(package, apdu); + } else { mp::odr odr; @@ -933,6 +1053,54 @@ void yf::SessionShared::process(mp::Package &package) const m_p->release_frontend(package); } +void yf::SessionShared::configure(const xmlNode *ptr) +{ + for (ptr = ptr->children; ptr; ptr = ptr->next) + { + if (ptr->type != XML_ELEMENT_NODE) + continue; + if (!strcmp((const char *) ptr->name, "resultset")) + { + const struct _xmlAttr *attr; + for (attr = ptr->properties; attr; attr = attr->next) + { + if (!strcmp((const char *) attr->name, "ttl")) + m_p->m_resultset_ttl = + mp::xml::get_int(attr->children, 30); + else if (!strcmp((const char *) attr->name, "max")) + { + m_p->m_resultset_max = + mp::xml::get_int(attr->children, 10); + } + else + throw mp::filter::FilterException( + "Bad attribute " + std::string((const char *) + attr->name)); + } + } + else if (!strcmp((const char *) ptr->name, "session")) + { + const struct _xmlAttr *attr; + for (attr = ptr->properties; attr; attr = attr->next) + { + if (!strcmp((const char *) attr->name, "ttl")) + m_p->m_session_ttl = + mp::xml::get_int(attr->children, 120); + else + throw mp::filter::FilterException( + "Bad attribute " + std::string((const char *) + attr->name)); + } + } + else + { + throw mp::filter::FilterException("Bad element " + + std::string((const char *) + ptr->name)); + } + } +} + static mp::filter::Base* filter_creator() { return new mp::filter::SessionShared;