Updated footer comment
[metaproxy-moved-to-github.git] / src / filter_session_shared.cpp
index 6d76a7b..b7e5235 100644 (file)
@@ -1,8 +1,20 @@
-/* $Id: filter_session_shared.cpp,v 1.15 2006-06-21 10:06:07 adam Exp $
-   Copyright (c) 2005-2006, Index Data.
+/* This file is part of Metaproxy.
+   Copyright (C) 2005-2008 Index Data
 
-   See the LICENSE file for details
- */
+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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
 
 #include "config.hpp"
 
@@ -34,6 +46,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;
@@ -41,13 +54,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);
@@ -55,6 +68,7 @@ namespace metaproxy_1 {
         private:
             SessionShared::Rep *m_p;
         };
+        // backend result set
         class SessionShared::BackendSet {
         public:
             std::string m_result_set_id;
@@ -70,8 +84,10 @@ namespace metaproxy_1 {
             bool search(
                 Package &frontend_package,
                 const Z_APDU *apdu_req,
-                const BackendInstancePtr bp);
+                const BackendInstancePtr bp,
+                bool &fatal_error);
         };
+        // backend connection instance
         class SessionShared::BackendInstance {
             friend class Rep;
             friend class BackendClass;
@@ -86,6 +102,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;
@@ -96,7 +113,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;
@@ -111,6 +128,7 @@ namespace metaproxy_1 {
                          int session_ttl);
             ~BackendClass();
         };
+        // frontend result set
         class SessionShared::FrontendSet {
             Databases m_databases;
             yazpp_1::Yaz_Z_Query m_query;
@@ -122,6 +140,7 @@ namespace metaproxy_1 {
                 const yazpp_1::Yaz_Z_Query &query);
             FrontendSet();
         };
+        // frontend session
         struct SessionShared::Frontend {
             Frontend(Rep *rep);
             ~Frontend();
@@ -145,6 +164,7 @@ namespace metaproxy_1 {
             BackendClassPtr m_backend_class;
             FrontendSets m_frontend_sets;
         };            
+        // representation
         class SessionShared::Rep {
             friend class SessionShared;
             friend struct Frontend;
@@ -258,7 +278,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++;
     }
@@ -407,14 +435,10 @@ void yf::SessionShared::Rep::init(mp::Package &package, const Z_GDU *gdu,
                                                m_session_ttl));
             m_backend_map[k] = b;
             frontend->m_backend_class = b;
-            std::cout << "SessionShared::Rep::init new session " 
-                      << frontend->m_backend_class << "\n";
         }
         else
         {
             frontend->m_backend_class = it->second;            
-            std::cout << "SessionShared::Rep::init existing session "
-                      << frontend->m_backend_class << "\n";
         }
     }
     BackendClassPtr bc = frontend->m_backend_class;
@@ -468,7 +492,8 @@ yf::SessionShared::BackendSet::BackendSet(
 bool yf::SessionShared::BackendSet::search(
     mp::Package &frontend_package,
     const Z_APDU *frontend_apdu,
-    const BackendInstancePtr bp)
+    const BackendInstancePtr bp,
+    bool & fatal_error)
 {
     Package search_package(bp->m_session, frontend_package.origin());
 
@@ -492,7 +517,8 @@ bool yf::SessionShared::BackendSet::search(
     search_package.request() = apdu_req;
 
     search_package.move();
-    
+    fatal_error = false;  // assume backend session is good
+
     Z_Records *z_records_diag = 0;
     Z_GDU *gdu = search_package.response().get();
     if (!search_package.session().is_closed()
@@ -508,11 +534,15 @@ bool yf::SessionShared::BackendSet::search(
         }
         if (z_records_diag)
         {
+            // there could be diagnostics that are so bad.. that 
+            // we simply mark the error as fatal..  For now we assume
+            // we can resume
             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->searchStatus = *b_resp->searchStatus;
                 f_resp->records = z_records_diag;
                 frontend_package.response() = f_apdu;
                 return false;
@@ -541,6 +571,7 @@ bool yf::SessionShared::BackendSet::search(
         f_apdu = odr.create_close(
             frontend_apdu, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0);
     frontend_package.response() = f_apdu;
+    fatal_error = true; // weired response.. bad backend
     return false;
 }
 
@@ -566,7 +597,6 @@ void yf::SessionShared::Frontend::override_set(
                     found_backend = *it;
                     result_set_id = (*set_it)->m_result_set_id;
                     found_backend->m_sets.erase(set_it);
-                    std::cout << "REUSE TTL SET: " << result_set_id << "\n";
                     return;
                 }
             }
@@ -587,7 +617,6 @@ void yf::SessionShared::Frontend::override_set(
             }
             else
                 result_set_id = "default";
-            std::cout << "AVAILABLE SET: " << result_set_id << "\n";
             return;
         }
     }
@@ -622,8 +651,6 @@ void yf::SessionShared::Frontend::get_set(mp::Package &package,
                         found_backend = *it;
                         bc->use_backend(found_backend);
                         found_set->timestamp();
-                        std::cout << "MATCH SET: " << 
-                            found_set->m_result_set_id << "\n";
                         // found matching set. No need to search again
                         return;
                     }
@@ -661,8 +688,6 @@ void yf::SessionShared::Frontend::get_set(mp::Package &package,
             package.response() = f_apdu;
             return;
         }
-        std::cout << "NEW " << found_backend << "\n";
-        
         if (bc->m_named_result_sets)
         {
             result_set_id = boost::io::str(
@@ -671,15 +696,17 @@ void yf::SessionShared::Frontend::get_set(mp::Package &package,
         }
         else
             result_set_id = "default";
-        std::cout << "NEW SET: " << result_set_id << "\n";
     }
     // we must search ...
     BackendSetPtr new_set(new BackendSet(result_set_id,
                                          databases, query));
-    if (!new_set->search(package, apdu_req, found_backend))
+    bool fatal_error = false;
+    if (!new_set->search(package, apdu_req, found_backend, fatal_error))
     {
-        std::cout << "search error\n";
-        bc->remove_backend(found_backend);
+        if (fatal_error)
+            bc->remove_backend(found_backend);
+        else
+            bc->release_backend(found_backend);
         return; // search error 
     }
     found_set = new_set;
@@ -852,7 +879,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);
@@ -860,12 +887,10 @@ void yf::SessionShared::BackendClass::expire()
     BackendInstanceList::iterator bit = m_backend_list.begin();
     while (bit != m_backend_list.end())
     {
-        std::cout << "expiry ";
         time_t last_use = (*bit)->m_time_last_use;
         
         if ((*bit)->m_in_use)
         {
-            std::cout << "inuse";
             bit++;
         }
         else if ((now >= last_use && now - last_use > m_backend_expiry_ttl)
@@ -878,14 +903,11 @@ void yf::SessionShared::BackendClass::expire()
             (*bit)->m_close_package->move();
 
             bit = m_backend_list.erase(bit);
-            std::cout << "erase";
         }
         else
         {
-            std::cout << "keep";
             bit++;
         }
-        std::cout << std::endl;
     }
 }
 
@@ -897,11 +919,10 @@ void yf::SessionShared::Rep::expire()
         boost::xtime_get(&xt, boost::TIME_UTC);
         xt.sec += 30;
         boost::thread::sleep(xt);
-        std::cout << "." << std::endl;
         
         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();
     }
 }
 
@@ -1038,7 +1059,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)
     {
@@ -1102,8 +1123,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
  */
+