X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_session_shared.cpp;h=55c45a7039cccff7ca91a1398d4f7a6384de736d;hb=9a318d33c4c99ee4158d39e3a62988af0229d7cf;hp=f0f84f7803d70831b3ae33134a4c2f58d2220336;hpb=74d5524719194de5dc96abd552562fa473088677;p=metaproxy-moved-to-github.git diff --git a/src/filter_session_shared.cpp b/src/filter_session_shared.cpp index f0f84f7..55c45a7 100644 --- a/src/filter_session_shared.cpp +++ b/src/filter_session_shared.cpp @@ -1,5 +1,5 @@ /* This file is part of Metaproxy. - Copyright (C) 2005-2010 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 @@ -85,6 +85,7 @@ namespace metaproxy_1 { const yazpp_1::Yaz_Z_Query &query); bool search( Package &frontend_package, + Package &search_package, const Z_APDU *apdu_req, const BackendInstancePtr bp, Z_Records **z_records); @@ -103,6 +104,7 @@ namespace metaproxy_1 { time_t m_time_last_use; mp::Package * m_close_package; ~BackendInstance(); + void timestamp(); }; // backends of some class (all with same InitKey) class SessionShared::BackendClass : boost::noncopyable { @@ -160,7 +162,8 @@ namespace metaproxy_1 { BackendInstancePtr &found_backend, BackendSetPtr &found_set); void override_set(BackendInstancePtr &found_backend, - std::string &result_set_id); + std::string &result_set_id, + const Databases &databases); Rep *m_p; BackendClassPtr m_backend_class; @@ -190,6 +193,7 @@ namespace metaproxy_1 { int m_resultset_ttl; int m_resultset_max; int m_session_ttl; + bool m_optimize_search; }; } } @@ -329,10 +333,15 @@ yf::SessionShared::BackendClass::get_backend( void yf::SessionShared::BackendClass::use_backend(BackendInstancePtr backend) { backend->m_in_use = true; - time(&backend->m_time_last_use); backend->m_sequence_this = m_sequence_top++; } +void yf::SessionShared::BackendInstance::timestamp() +{ + assert(m_in_use); + time(&m_time_last_use); +} + yf::SessionShared::BackendInstance::~BackendInstance() { delete m_close_package; @@ -506,14 +515,11 @@ static int get_diagnostic(Z_DefaultDiagFormat *r) bool yf::SessionShared::BackendSet::search( mp::Package &frontend_package, + mp::Package &search_package, const Z_APDU *frontend_apdu, const BackendInstancePtr bp, Z_Records **z_records) { - Package search_package(bp->m_session, frontend_package.origin()); - - search_package.copy_filter(frontend_package); - mp::odr odr; Z_APDU *apdu_req = zget_APDU(odr, Z_APDU_searchRequest); Z_SearchRequest *req = apdu_req->u.searchRequest; @@ -529,6 +535,10 @@ bool yf::SessionShared::BackendSet::search( for (; it != m_databases.end(); it++) req->databaseNames[i++] = odr_strdup(odr, it->c_str()); + if (frontend_apdu->which == Z_APDU_searchRequest) + req->preferredRecordSyntax = + frontend_apdu->u.searchRequest->preferredRecordSyntax; + search_package.request() = apdu_req; search_package.move(); @@ -559,13 +569,15 @@ bool yf::SessionShared::BackendSet::search( void yf::SessionShared::Frontend::override_set( BackendInstancePtr &found_backend, - std::string &result_set_id) + std::string &result_set_id, + const Databases &databases) { BackendClassPtr bc = m_backend_class; BackendInstanceList::const_iterator it = bc->m_backend_list.begin(); time_t now; time(&now); - + + size_t max_sets = bc->m_named_result_sets ? bc->m_backend_set_max : 1; for (; it != bc->m_backend_list.end(); it++) { if (!(*it)->m_in_use) @@ -573,8 +585,10 @@ void yf::SessionShared::Frontend::override_set( BackendSetList::iterator set_it = (*it)->m_sets.begin(); for (; set_it != (*it)->m_sets.end(); set_it++) { - if (now >= (*set_it)->m_time_last_use && - now - (*set_it)->m_time_last_use > bc->m_backend_set_ttl) + if ((max_sets > 1 || (*set_it)->m_databases == databases) + && + (now < (*set_it)->m_time_last_use || + now - (*set_it)->m_time_last_use >= bc->m_backend_set_ttl)) { found_backend = *it; result_set_id = (*set_it)->m_result_set_id; @@ -584,7 +598,6 @@ void yf::SessionShared::Frontend::override_set( } } } - size_t max_sets = bc->m_named_result_sets ? bc->m_backend_set_max : 1; for (it = bc->m_backend_list.begin(); it != bc->m_backend_list.end(); it++) { if (!(*it)->m_in_use && (*it)->m_sets.size() < max_sets) @@ -618,30 +631,33 @@ restart: BackendClassPtr bc = m_backend_class; { boost::mutex::scoped_lock lock(bc->m_mutex_backend_class); - // look at each backend and see if we have a similar search - BackendInstanceList::const_iterator it = bc->m_backend_list.begin(); - for (; it != bc->m_backend_list.end(); it++) + if (m_p->m_optimize_search) { - if (!(*it)->m_in_use) + // look at each backend and see if we have a similar search + BackendInstanceList::const_iterator it = bc->m_backend_list.begin(); + for (; it != bc->m_backend_list.end(); it++) { - BackendSetList::const_iterator set_it = (*it)->m_sets.begin(); - for (; set_it != (*it)->m_sets.end(); set_it++) + if (!(*it)->m_in_use) { - if ((*set_it)->m_databases == databases - && query.match(&(*set_it)->m_query)) + BackendSetList::const_iterator set_it = (*it)->m_sets.begin(); + for (; set_it != (*it)->m_sets.end(); set_it++) { - found_set = *set_it; - found_backend = *it; - bc->use_backend(found_backend); - found_set->timestamp(); - // found matching set. No need to search again - return; + if ((*set_it)->m_databases == databases + && query.match(&(*set_it)->m_query)) + { + found_set = *set_it; + found_backend = *it; + bc->use_backend(found_backend); + found_set->timestamp(); + // found matching set. No need to search again + return; + } } } } } - override_set(found_backend, result_set_id); + override_set(found_backend, result_set_id, databases); if (found_backend) bc->use_backend(found_backend); } @@ -681,11 +697,18 @@ restart: else result_set_id = "default"; } + found_backend->timestamp(); + // we must search ... BackendSetPtr new_set(new BackendSet(result_set_id, databases, query)); Z_Records *z_records = 0; - if (!new_set->search(package, apdu_req, found_backend, &z_records)) + + Package search_package(found_backend->m_session, package.origin()); + search_package.copy_filter(package); + + if (!new_set->search(package, search_package, + apdu_req, found_backend, &z_records)) { bc->remove_backend(found_backend); return; // search error @@ -870,6 +893,8 @@ void yf::SessionShared::Frontend::present(mp::Package &package, bc->release_backend(found_backend); return; } + + found_backend->timestamp(); Z_APDU *p_apdu = zget_APDU(odr, Z_APDU_presentRequest); Z_PresentRequest *p_req = p_apdu->u.presentRequest; @@ -943,6 +968,7 @@ void yf::SessionShared::Frontend::scan(mp::Package &frontend_package, else { Package scan_package(backend->m_session, frontend_package.origin()); + backend->timestamp(); scan_package.copy_filter(frontend_package); scan_package.request() = apdu_req; scan_package.move(); @@ -980,8 +1006,7 @@ void yf::SessionShared::BackendClass::expire_class() { bit++; } - else if ((now >= last_use && now - last_use > m_backend_expiry_ttl) - || (now < last_use)) + else if (now < last_use || now - last_use > m_backend_expiry_ttl) { mp::odr odr; (*bit)->m_close_package->response() = odr.create_close( @@ -1004,7 +1029,7 @@ void yf::SessionShared::Rep::expire() { boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC); - xt.sec += 30; + xt.sec += m_session_ttl / 3; boost::thread::sleep(xt); BackendClassMap::const_iterator b_it = m_backend_map.begin(); @@ -1018,6 +1043,7 @@ yf::SessionShared::Rep::Rep() m_resultset_ttl = 30; m_resultset_max = 10; m_session_ttl = 90; + m_optimize_search = true; } void yf::SessionShared::Rep::start() @@ -1154,7 +1180,8 @@ void yf::SessionShared::process(mp::Package &package) const m_p->release_frontend(package); } -void yf::SessionShared::configure(const xmlNode *ptr, bool test_only) +void yf::SessionShared::configure(const xmlNode *ptr, bool test_only, + const char *path) { for (ptr = ptr->children; ptr; ptr = ptr->next) { @@ -1173,6 +1200,11 @@ void yf::SessionShared::configure(const xmlNode *ptr, bool test_only) m_p->m_resultset_max = mp::xml::get_int(attr->children, 10); } + else if (!strcmp((const char *) attr->name, "optimizesearch")) + { + m_p->m_optimize_search = + mp::xml::get_bool(attr->children, true); + } else throw mp::filter::FilterException( "Bad attribute " + std::string((const char *)