BackendSetPtr &found_set);
void override_set(BackendInstancePtr &found_backend,
std::string &result_set_id,
- const Databases &databases);
+ const Databases &databases,
+ bool out_of_sessions);
Rep *m_p;
BackendClassPtr m_backend_class;
int m_resultset_max;
int m_session_ttl;
bool m_optimize_search;
+ bool m_restart;
+ int m_session_max;
};
}
}
}
}
BackendClassPtr bc = frontend->m_backend_class;
- BackendInstancePtr backend = bc->get_backend(package);
-
+ BackendInstancePtr backend;
mp::odr odr;
- if (!backend)
+
+ // we only need to get init response from "first" target in
+ // backend class - the assumption being that init response is
+ // same for all
+ if (bc->m_init_response.get() == 0)
{
- Z_APDU *apdu = odr.create_initResponse(gdu->u.z3950, 0, 0);
- *apdu->u.initResponse->result = 0;
- package.response() = apdu;
- package.session().close();
+ backend = bc->get_backend(package);
}
- else
{
boost::mutex::scoped_lock lock(bc->m_mutex_backend_class);
- 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);
-
- 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 (bc->m_init_response.get() == 0)
+ {
+ Z_APDU *apdu = odr.create_initResponse(gdu->u.z3950, 0, 0);
+ *apdu->u.initResponse->result = 0;
+ package.response() = apdu;
+ package.session().close();
+ }
+ else
+ {
+ 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);
+
+ 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);
void yf::SessionShared::Frontend::override_set(
BackendInstancePtr &found_backend,
std::string &result_set_id,
- const Databases &databases)
+ const Databases &databases,
+ bool out_of_sessions)
{
BackendClassPtr bc = m_backend_class;
BackendInstanceList::const_iterator it = bc->m_backend_list.begin();
{
if ((max_sets > 1 || (*set_it)->m_databases == databases)
&&
- (now < (*set_it)->m_time_last_use ||
+ (out_of_sessions ||
+ now < (*set_it)->m_time_last_use ||
now - (*set_it)->m_time_last_use >= bc->m_backend_set_ttl))
{
found_backend = *it;
restart:
std::string result_set_id;
+ bool out_of_sessions = false;
BackendClassPtr bc = m_backend_class;
{
boost::mutex::scoped_lock lock(bc->m_mutex_backend_class);
+
+ if ((int) bc->m_backend_list.size() >= m_p->m_session_max)
+ out_of_sessions = true;
if (m_p->m_optimize_search)
{
}
}
}
- override_set(found_backend, result_set_id, databases);
+ override_set(found_backend, result_set_id, databases, out_of_sessions);
if (found_backend)
bc->use_backend(found_backend);
}
if (!found_backend)
{
- // create a new backend set (and new set)
- found_backend = bc->create_backend(package);
+ // create a new backend set (and new set) if we're not out of sessions
+ if (!out_of_sessions)
+ found_backend = bc->create_backend(package);
if (!found_backend)
{
Z_APDU *f_apdu = 0;
mp::odr odr;
+ const char *addinfo = 0;
+
+ if (out_of_sessions)
+ addinfo = "session_shared: all sessions in use";
if (apdu_req->which == Z_APDU_searchRequest)
{
f_apdu = odr.create_searchResponse(
- apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0);
+ apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, addinfo);
}
else if (apdu_req->which == Z_APDU_presentRequest)
{
f_apdu = odr.create_presentResponse(
- apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0);
+ apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, addinfo);
}
else
{
f_apdu = odr.create_close(
- apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, 0);
+ apdu_req, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR, addinfo);
}
package.response() = f_apdu;
return;
}
}
- if (!session_restarted &&
+ if (m_p->m_restart && !session_restarted &&
condition == YAZ_BIB1_TEMPORARY_SYSTEM_ERROR)
{
+ package.log("session_shared", YLOG_LOG, "restart");
bc->remove_backend(found_backend);
session_restarted = true;
found_backend.reset();
return; // search error
}
}
- if (!session_restarted && new_set->m_result_set_size < 0)
+ if (m_p->m_restart && !session_restarted && new_set->m_result_set_size < 0)
{
+ package.log("session_shared", YLOG_LOG, "restart");
bc->remove_backend(found_backend);
session_restarted = true;
found_backend.reset();
query.set_Z_Query(req->query);
Databases databases;
int i;
- for (i = 0; i<req->num_databaseNames; i++)
+ for (i = 0; i < req->num_databaseNames; i++)
databases.push_back(req->databaseNames[i]);
BackendSetPtr found_set; // null
m_resultset_max = 10;
m_session_ttl = 90;
m_optimize_search = true;
+ m_restart = true;
+ m_session_max = 100;
}
void yf::SessionShared::Rep::start()
m_p->m_optimize_search =
mp::xml::get_bool(attr->children, true);
}
+ else if (!strcmp((const char *) attr->name, "restart"))
+ {
+ m_p->m_restart = mp::xml::get_bool(attr->children, true);
+ }
else
throw mp::filter::FilterException(
"Bad attribute " + std::string((const char *)
{
if (!strcmp((const char *) attr->name, "ttl"))
m_p->m_session_ttl =
- mp::xml::get_int(attr->children, 120);
+ mp::xml::get_int(attr->children, 90);
+ else if (!strcmp((const char *) attr->name, "max"))
+ m_p->m_session_max =
+ mp::xml::get_int(attr->children, 100);
else
throw mp::filter::FilterException(
"Bad attribute " + std::string((const char *)