X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Ffilter_session_shared.cpp;h=b6c564614ec0d9ec31bb587b7beb51aa22c6c392;hb=edeb7dc220cc1b66ae533ee4baba40b15732a4fd;hp=038b46723adcfe7c51f2e6ac617647bc85c51dc5;hpb=6de003d8fb16f703d2c71c21128423cf691ce45d;p=metaproxy-moved-to-github.git diff --git a/src/filter_session_shared.cpp b/src/filter_session_shared.cpp index 038b467..b6c5646 100644 --- a/src/filter_session_shared.cpp +++ b/src/filter_session_shared.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include "filter_session_shared.hpp" +#include #include #include #include @@ -117,7 +118,7 @@ namespace metaproxy_1 { BackendInstancePtr get_backend(const Package &package); void use_backend(BackendInstancePtr b); void release_backend(BackendInstancePtr b); - void expire_class(); + bool expire_instances(); yazpp_1::GDU m_init_request; yazpp_1::GDU m_init_response; boost::mutex m_mutex_backend_class; @@ -159,6 +160,9 @@ namespace metaproxy_1 { void present(Package &package, Z_APDU *apdu); void scan(Package &package, Z_APDU *apdu); + int result_set_ref(ODR o, + const Databases &databases, + Z_RPNStructure *s, std::string &rset); void get_set(mp::Package &package, const Z_APDU *apdu_req, const Databases &databases, @@ -185,6 +189,8 @@ namespace metaproxy_1 { public: void expire(); private: + void expire_classes(); + void stat(); void init(Package &package, const Z_GDU *gdu, FrontendPtr frontend); void start(); @@ -454,6 +460,26 @@ yf::SessionShared::BackendClass::BackendClass(const yazpp_1::GDU &init_request, yf::SessionShared::BackendClass::~BackendClass() {} +void yf::SessionShared::Rep::stat() +{ + int no_classes = 0; + int no_instances = 0; + BackendClassMap::const_iterator it; + { + boost::mutex::scoped_lock lock(m_mutex_backend_map); + for (it = m_backend_map.begin(); it != m_backend_map.end(); it++) + { + BackendClassPtr bc = it->second; + no_classes++; + BackendInstanceList::iterator bit = bc->m_backend_list.begin(); + for (; bit != bc->m_backend_list.end(); bit++) + no_instances++; + } + } + yaz_log(YLOG_LOG, "backend classes=%d instances=%d", no_classes, + no_instances); +} + void yf::SessionShared::Rep::init(mp::Package &package, const Z_GDU *gdu, FrontendPtr frontend) { @@ -844,6 +870,54 @@ restart: found_backend->m_sets.push_back(found_set); } +int yf::SessionShared::Frontend::result_set_ref(ODR o, + const Databases &databases, + Z_RPNStructure *s, + std::string &rset) +{ + int ret = 0; + switch (s->which) + { + case Z_RPNStructure_simple: + if (s->u.simple->which == Z_Operand_resultSetId) + { + const char *id = s->u.simple->u.resultSetId; + rset = id; + + FrontendSets::iterator fset_it = m_frontend_sets.find(id); + if (fset_it == m_frontend_sets.end()) + { + ret = YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST; + } + else if (fset_it->second->get_databases() != databases) + { + ret = YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST; + } + else + { + yazpp_1::Yaz_Z_Query query = fset_it->second->get_query(); + Z_Query *q = yaz_copy_Z_Query(query.get_Z_Query(), o); + if (q->which == Z_Query_type_1 || q->which == Z_Query_type_101) + { + s->which = q->u.type_1->RPNStructure->which; + s->u.simple = q->u.type_1->RPNStructure->u.simple; + } + else + { + ret = YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST; + } + } + } + break; + case Z_RPNStructure_complex: + ret = result_set_ref(o, databases, s->u.complex->s1, rset); + if (!ret) + ret = result_set_ref(o, databases, s->u.complex->s2, rset); + break; + } + return ret; +} + void yf::SessionShared::Frontend::search(mp::Package &package, Z_APDU *apdu_req) { @@ -864,19 +938,40 @@ void yf::SessionShared::Frontend::search(mp::Package &package, YAZ_BIB1_RESULT_SET_EXISTS_AND_REPLACE_INDICATOR_OFF, 0); package.response() = apdu; - return; } m_frontend_sets.erase(fset_it); } - yazpp_1::Yaz_Z_Query query; - query.set_Z_Query(req->query); Databases databases; int i; for (i = 0; i < req->num_databaseNames; i++) databases.push_back(req->databaseNames[i]); + + yazpp_1::Yaz_Z_Query query; + query.set_Z_Query(req->query); + + Z_Query *q = query.get_Z_Query(); + if (q->which == Z_Query_type_1 || q->which == Z_Query_type_101) + { + mp::odr odr; + std::string rset; + int diag = result_set_ref(odr, databases, q->u.type_1->RPNStructure, + rset); + if (diag) + { + Z_APDU *apdu = + odr.create_searchResponse( + apdu_req, + diag, + rset.c_str()); + package.response() = apdu; + return; + } + query.set_Z_Query(q); + } + BackendSetPtr found_set; // null BackendInstancePtr found_backend; // null @@ -992,11 +1087,13 @@ void yf::SessionShared::Frontend::present(mp::Package &package, if (b_resp->records && b_resp->records->which == Z_Records_DBOSD) { +#if 0 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); +#endif found_set->m_record_cache.add( odr, b_resp->records->u.databaseOrSurDiagnostics, @@ -1056,7 +1153,7 @@ void yf::SessionShared::Worker::operator() (void) m_p->expire(); } -void yf::SessionShared::BackendClass::expire_class() +bool yf::SessionShared::BackendClass::expire_instances() { time_t now; time(&now); @@ -1085,6 +1182,25 @@ void yf::SessionShared::BackendClass::expire_class() bit++; } } + if (m_backend_list.empty()) + return true; + return false; +} + +void yf::SessionShared::Rep::expire_classes() +{ + boost::mutex::scoped_lock lock(m_mutex_backend_map); + BackendClassMap::iterator b_it = m_backend_map.begin(); + while (b_it != m_backend_map.end()) + { + if (b_it->second->expire_instances()) + { + m_backend_map.erase(b_it); + b_it = m_backend_map.begin(); + } + else + b_it++; + } } void yf::SessionShared::Rep::expire() @@ -1102,9 +1218,8 @@ void yf::SessionShared::Rep::expire() xt.sec += m_session_ttl / 3; boost::thread::sleep(xt); - BackendClassMap::const_iterator b_it = m_backend_map.begin(); - for (; b_it != m_backend_map.end(); b_it++) - b_it->second->expire_class(); + stat(); + expire_classes(); } }