X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_session_shared.cpp;h=ab518aa3d6d912dd0120c6e6809785c282cb9c83;hb=b0c61b7f8b17d876c88347a96c246c47493140da;hp=c4d8a8c670776323cb68801e36958c8e428e9786;hpb=263db488835e22820d79a4ffa46fb892b7837fd4;p=metaproxy-moved-to-github.git diff --git a/src/filter_session_shared.cpp b/src/filter_session_shared.cpp index c4d8a8c..ab518aa 100644 --- a/src/filter_session_shared.cpp +++ b/src/filter_session_shared.cpp @@ -1,7 +1,5 @@ -/* $Id: filter_session_shared.cpp,v 1.19 2008-01-21 15:23:11 adam Exp $ - Copyright (c) 2005-2007, Index Data. - -This file is part of Metaproxy. +/* This file is part of Metaproxy. + Copyright (C) 2005-2010 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 @@ -14,10 +12,9 @@ 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. - */ +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ #include "config.hpp" @@ -39,6 +36,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#include #include #include #include @@ -49,6 +47,7 @@ namespace yf = metaproxy_1::filter; namespace metaproxy_1 { namespace filter { + // key for session.. We'll only share sessions with same InitKey class SessionShared::InitKey { public: bool operator < (const SessionShared::InitKey &k) const; @@ -56,13 +55,13 @@ namespace metaproxy_1 { InitKey(const InitKey &); ~InitKey(); private: - InitKey &operator = (const InitKey &k); char *m_idAuthentication_buf; int m_idAuthentication_size; char *m_otherInfo_buf; int m_otherInfo_size; ODR m_odr; }; + // worker thread .. for expiry of sessions class SessionShared::Worker { public: Worker(SessionShared::Rep *rep); @@ -70,6 +69,7 @@ namespace metaproxy_1 { private: SessionShared::Rep *m_p; }; + // backend result set class SessionShared::BackendSet { public: std::string m_result_set_id; @@ -78,6 +78,7 @@ namespace metaproxy_1 { yazpp_1::Yaz_Z_Query m_query; time_t m_time_last_use; void timestamp(); + yazpp_1::RecordCache m_record_cache; BackendSet( const std::string &result_set_id, const Databases &databases, @@ -85,8 +86,10 @@ namespace metaproxy_1 { bool search( Package &frontend_package, const Z_APDU *apdu_req, - const BackendInstancePtr bp); + const BackendInstancePtr bp, + Z_Records **z_records); }; + // backend connection instance class SessionShared::BackendInstance { friend class Rep; friend class BackendClass; @@ -101,6 +104,7 @@ namespace metaproxy_1 { mp::Package * m_close_package; ~BackendInstance(); }; + // backends of some class (all with same InitKey) class SessionShared::BackendClass : boost::noncopyable { friend class Rep; friend struct Frontend; @@ -111,7 +115,7 @@ namespace metaproxy_1 { BackendInstancePtr get_backend(const Package &package); void use_backend(BackendInstancePtr b); void release_backend(BackendInstancePtr b); - void expire(); + void expire_class(); yazpp_1::GDU m_init_request; yazpp_1::GDU m_init_response; boost::mutex m_mutex_backend_class; @@ -126,6 +130,7 @@ namespace metaproxy_1 { int session_ttl); ~BackendClass(); }; + // frontend result set class SessionShared::FrontendSet { Databases m_databases; yazpp_1::Yaz_Z_Query m_query; @@ -137,6 +142,7 @@ namespace metaproxy_1 { const yazpp_1::Yaz_Z_Query &query); FrontendSet(); }; + // frontend session struct SessionShared::Frontend { Frontend(Rep *rep); ~Frontend(); @@ -160,6 +166,7 @@ namespace metaproxy_1 { BackendClassPtr m_backend_class; FrontendSets m_frontend_sets; }; + // representation class SessionShared::Rep { friend class SessionShared; friend struct Frontend; @@ -273,7 +280,15 @@ void yf::SessionShared::BackendClass::remove_backend(BackendInstancePtr b) while (it != m_backend_list.end()) { if (*it == b) + { + mp::odr odr; + (*it)->m_close_package->response() = odr.create_close( + 0, Z_Close_lackOfActivity, 0); + (*it)->m_close_package->session().close(); + (*it)->m_close_package->move(); + it = m_backend_list.erase(it); + } else it++; } @@ -476,10 +491,16 @@ yf::SessionShared::BackendSet::BackendSet( timestamp(); } +static int get_diagnostic(Z_DefaultDiagFormat *r) +{ + return *r->condition; +} + bool yf::SessionShared::BackendSet::search( mp::Package &frontend_package, const Z_APDU *frontend_apdu, - const BackendInstancePtr bp) + const BackendInstancePtr bp, + Z_Records **z_records) { Package search_package(bp->m_session, frontend_package.origin()); @@ -503,41 +524,14 @@ bool yf::SessionShared::BackendSet::search( search_package.request() = apdu_req; search_package.move(); - - Z_Records *z_records_diag = 0; + Z_GDU *gdu = search_package.response().get(); if (!search_package.session().is_closed() && gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which == Z_APDU_searchResponse) { Z_SearchResponse *b_resp = gdu->u.z3950->u.searchResponse; - if (b_resp->records) - { - if (b_resp->records->which == Z_Records_NSD - || b_resp->records->which == Z_Records_multipleNSD) - z_records_diag = b_resp->records; - } - if (z_records_diag) - { - if (frontend_apdu->which == Z_APDU_searchRequest) - { - Z_APDU *f_apdu = odr.create_searchResponse(frontend_apdu, - 0, 0); - Z_SearchResponse *f_resp = f_apdu->u.searchResponse; - f_resp->records = z_records_diag; - frontend_package.response() = f_apdu; - return false; - } - if (frontend_apdu->which == Z_APDU_presentRequest) - { - Z_APDU *f_apdu = odr.create_presentResponse(frontend_apdu, - 0, 0); - Z_PresentResponse *f_resp = f_apdu->u.presentResponse; - f_resp->records = z_records_diag; - frontend_package.response() = f_apdu; - return false; - } - } + *z_records = b_resp->records; m_result_set_size = *b_resp->resultCount; return true; } @@ -609,6 +603,9 @@ void yf::SessionShared::Frontend::get_set(mp::Package &package, BackendInstancePtr &found_backend, BackendSetPtr &found_set) { + bool session_restarted = false; + +restart: std::string result_set_id; BackendClassPtr bc = m_backend_class; { @@ -680,11 +677,76 @@ void yf::SessionShared::Frontend::get_set(mp::Package &package, // we must search ... BackendSetPtr new_set(new BackendSet(result_set_id, databases, query)); - if (!new_set->search(package, apdu_req, found_backend)) + Z_Records *z_records = 0; + if (!new_set->search(package, apdu_req, found_backend, &z_records)) { bc->remove_backend(found_backend); return; // search error } + + if (z_records) + { + int condition = 0; + if (z_records->which == Z_Records_NSD) + { + condition = + get_diagnostic(z_records->u.nonSurrogateDiagnostic); + } + else if (z_records->which == Z_Records_multipleNSD) + { + if (z_records->u.multipleNonSurDiagnostics->num_diagRecs >= 1 + && + + z_records->u.multipleNonSurDiagnostics->diagRecs[0]->which == + Z_DiagRec_defaultFormat) + { + condition = get_diagnostic( + z_records->u.multipleNonSurDiagnostics->diagRecs[0]->u.defaultFormat); + + } + } + if (!session_restarted && + condition == YAZ_BIB1_TEMPORARY_SYSTEM_ERROR) + { + bc->remove_backend(found_backend); + session_restarted = true; + found_backend.reset(); + goto restart; + + } + + if (condition) + { + mp::odr odr; + if (apdu_req->which == Z_APDU_searchRequest) + { + Z_APDU *f_apdu = odr.create_searchResponse(apdu_req, + 0, 0); + Z_SearchResponse *f_resp = f_apdu->u.searchResponse; + *f_resp->searchStatus = Z_SearchResponse_none; + f_resp->records = z_records; + package.response() = f_apdu; + } + if (apdu_req->which == Z_APDU_presentRequest) + { + Z_APDU *f_apdu = odr.create_presentResponse(apdu_req, + 0, 0); + Z_PresentResponse *f_resp = f_apdu->u.presentResponse; + f_resp->records = z_records; + package.response() = f_apdu; + } + bc->release_backend(found_backend); + return; // search error + } + } + if (!session_restarted && new_set->m_result_set_size < 0) + { + bc->remove_backend(found_backend); + session_restarted = true; + found_backend.reset(); + goto restart; + } + found_set = new_set; found_set->timestamp(); found_backend->m_sets.push_back(found_set); @@ -774,6 +836,34 @@ void yf::SessionShared::Frontend::present(mp::Package &package, if (!found_set) return; + Z_NamePlusRecordList *npr_res = 0; + if (found_set->m_record_cache.lookup(odr, &npr_res, + *req->resultSetStartPoint, + *req->numberOfRecordsRequested, + req->preferredRecordSyntax, + req->recordComposition)) + { + Z_APDU *f_apdu_res = odr.create_presentResponse(apdu_req, 0, 0); + Z_PresentResponse *f_resp = f_apdu_res->u.presentResponse; + + yaz_log(YLOG_LOG, "Found " ODR_INT_PRINTF "+" ODR_INT_PRINTF + " records in cache %p", + *req->resultSetStartPoint, + *req->numberOfRecordsRequested, + &found_set->m_record_cache); + + *f_resp->numberOfRecordsReturned = *req->numberOfRecordsRequested; + *f_resp->nextResultSetPosition = + *req->resultSetStartPoint + *req->numberOfRecordsRequested; + // f_resp->presentStatus assumed OK. + f_resp->records = (Z_Records *) odr_malloc(odr, sizeof(Z_Records)); + f_resp->records->which = Z_Records_DBOSD; + f_resp->records->u.databaseOrSurDiagnostics = npr_res; + package.response() = f_apdu_res; + bc->release_backend(found_backend); + return; + } + Z_APDU *p_apdu = zget_APDU(odr, Z_APDU_presentRequest); Z_PresentRequest *p_req = p_apdu->u.presentRequest; p_req->preferredRecordSyntax = req->preferredRecordSyntax; @@ -805,6 +895,20 @@ void yf::SessionShared::Frontend::present(mp::Package &package, f_resp->records = b_resp->records; f_resp->otherInfo = b_resp->otherInfo; package.response() = f_apdu_res; + + if (b_resp->records && b_resp->records->which == Z_Records_DBOSD) + { + yaz_log(YLOG_LOG, "Adding " ODR_INT_PRINTF "+" ODR_INT_PRINTF + " records to cache %p", + *req->resultSetStartPoint, + *f_resp->numberOfRecordsReturned, + &found_set->m_record_cache); + found_set->m_record_cache.add( + odr, + b_resp->records->u.databaseOrSurDiagnostics, + *req->resultSetStartPoint, + *f_resp->numberOfRecordsReturned); + } bc->release_backend(found_backend); } else @@ -855,7 +959,7 @@ void yf::SessionShared::Worker::operator() (void) m_p->expire(); } -void yf::SessionShared::BackendClass::expire() +void yf::SessionShared::BackendClass::expire_class() { time_t now; time(&now); @@ -898,7 +1002,7 @@ void yf::SessionShared::Rep::expire() BackendClassMap::const_iterator b_it = m_backend_map.begin(); for (; b_it != m_backend_map.end(); b_it++) - b_it->second->expire(); + b_it->second->expire_class(); } } @@ -1035,7 +1139,7 @@ void yf::SessionShared::process(mp::Package &package) const m_p->release_frontend(package); } -void yf::SessionShared::configure(const xmlNode *ptr) +void yf::SessionShared::configure(const xmlNode *ptr, bool test_only) { for (ptr = ptr->children; ptr; ptr = ptr->next) { @@ -1099,8 +1203,9 @@ extern "C" { /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil - * c-file-style: "stroustrup" * End: * vim: shiftwidth=4 tabstop=8 expandtab */ +