/*
- * Copyright (c) 1998-2001, Index Data.
+ * Copyright (c) 1998-2003, Index Data.
* See the file LICENSE for details.
*
- * $Id: yaz-proxy.cpp,v 1.34 2002-09-10 11:58:13 adam Exp $
+ * $Id: yaz-proxy.cpp,v 1.43 2003-06-25 21:57:45 adam Exp $
*/
#include <assert.h>
#include <time.h>
#include <yaz/log.h>
-#include <yaz++/yaz-proxy.h>
+#include <yaz++/proxy.h>
Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable) :
Yaz_Z_Assoc(the_PDU_Observable)
m_proxy_authentication = 0;
m_max_clients = 50;
m_seed = time(0);
+ m_idletime = 600;
m_optimize = xstrdup ("1");
}
{
Yaz_Proxy *new_proxy = new Yaz_Proxy(the_PDU_Observable);
new_proxy->m_parent = this;
- new_proxy->timeout(500);
+ new_proxy->timeout(m_idletime);
new_proxy->set_proxy_target(m_proxyTarget);
new_proxy->set_APDU_log(get_APDU_log());
new_proxy->set_proxy_authentication(m_proxy_authentication);
c->m_last_resultCount = 0;
c->m_sr_transform = 0;
c->m_waiting = 0;
- c->timeout(600);
+ c->timeout(m_idletime);
}
c->m_seqno = parent->m_seqno;
if (c->m_server && c->m_server != this)
c->m_server->m_client = 0;
c->m_server = this;
- c->m_seqno = parent->m_seqno;
(parent->m_seqno)++;
yaz_log (LOG_DEBUG, "get_client 1 %p %p", this, c);
return c;
}
}
+ else if (!c)
+ {
+ Yaz_ProxyClient *cc = 0;
+
+ for (c = parent->m_clientPool; c; c = c->m_next)
+ {
+ assert (c->m_prev);
+ assert (*c->m_prev == c);
+ if (c->m_server == 0 && c->m_cookie[0] == 0 &&
+ !strcmp(m_proxyTarget, c->get_hostname()))
+ {
+ cc = c;
+ }
+ }
+ if (cc)
+ {
+ // found it in cache
+ c = cc;
+
+ yaz_log (LOG_LOG, "Reuse session %d to %d %s",
+ c->m_seqno, parent->m_seqno, c->get_hostname());
+
+ c->m_seqno = parent->m_seqno;
+ assert(c->m_server == 0);
+ c->m_server = this;
+
+ (parent->m_seqno)++;
+ return c;
+ }
+ }
if (!m_client)
{
if (apdu->which != Z_APDU_initRequest)
Yaz_ProxyClient *c_min = 0;
int min_seq = -1;
int no_of_clients = 0;
- yaz_log (LOG_LOG, "Existing sessions");
+ if (parent->m_clientPool)
+ yaz_log (LOG_LOG, "Existing sessions");
for (c = parent->m_clientPool; c; c = c->m_next)
{
yaz_log (LOG_LOG, " Session %-3d wait=%d %s", c->m_seqno,
}
else
{
- yaz_log (LOG_LOG, "Reuse session %d to %d",
- c->m_seqno, parent->m_seqno);
+ yaz_log (LOG_LOG, "Move session %d to %d %s",
+ c->m_seqno, parent->m_seqno, c->get_hostname());
if (cookie)
strcpy (c->m_cookie, cookie);
else
c->m_last_ok = 0;
c->m_sr_transform = 0;
c->m_waiting = 0;
- c->timeout(10);
+ c->timeout(20);
(parent->m_seqno)++;
}
{
if (apdu->which != Z_APDU_searchRequest)
return apdu;
- if (*m_parent->m_optimize != '1')
- return apdu;
+ if (*m_parent->m_optimize == '0')
+ return apdu; // don't optimize result sets..
Z_SearchRequest *sr = apdu->u.searchRequest;
Yaz_Z_Query *this_query = new Yaz_Z_Query;
Yaz_Z_Databases this_databases;
if (m_client->m_last_ok && m_client->m_last_query &&
m_client->m_last_query->match(this_query) &&
+ !strcmp(m_client->m_last_resultSetId, sr->resultSetName) &&
m_client->m_last_databases.match(this_databases))
{
delete this_query;
pr->referenceId = sr->referenceId;
pr->resultSetId = sr->resultSetName;
pr->preferredRecordSyntax = sr->preferredRecordSyntax;
- *pr->numberOfRecordsRequested = *sr->mediumSetPresentNumber;
+ if (*sr->mediumSetPresentNumber < m_client->m_last_resultCount)
+ *pr->numberOfRecordsRequested = *sr->mediumSetPresentNumber;
+ else
+ *pr->numberOfRecordsRequested = m_client->m_last_resultCount;
if (sr->mediumSetElementSetNames)
{
pr->recordComposition = (Z_RecordComposition *)
delete m_client->m_last_query;
m_client->m_last_query = this_query;
m_client->m_last_ok = 0;
+
+ xfree (m_client->m_last_resultSetId);
+ m_client->m_last_resultSetId = xstrdup (sr->resultSetName);
+
m_client->m_last_databases.set(sr->num_databaseNames,
(const char **) sr->databaseNames);
}
return "presentRequest";
case Z_APDU_presentResponse:
return "presentResponse";
+ case Z_APDU_deleteResultSetRequest:
+ return "deleteResultSetRequest";
+ case Z_APDU_deleteResultSetResponse:
+ return "deleteResultSetResponse";
+ case Z_APDU_scanRequest:
+ return "scanRequest";
+ case Z_APDU_scanResponse:
+ return "scanResponse";
+ case Z_APDU_sortRequest:
+ return "sortRequest";
+ case Z_APDU_sortResponse:
+ return "sortResponse";
+ case Z_APDU_extendedServicesRequest:
+ return "extendedServicesRequest";
+ case Z_APDU_extendedServicesResponse:
+ return "extendedServicesResponse";
+ case Z_APDU_close:
+ return "close";
}
return "other";
}
{
Z_APDU *apdu = m_client->m_initResponse;
apdu->u.initResponse->otherInfo = 0;
- if (m_client->m_cookie)
+ if (m_client->m_cookie && *m_client->m_cookie)
set_otherInformationString(apdu, VAL_COOKIE, 1,
m_client->m_cookie);
send_Z_PDU(apdu);
void Yaz_Proxy::shutdown()
{
- // only keep if keep_alive flag and cookie is set...
- if (m_keepalive && m_client && m_client->m_cookie[0])
+ // only keep if keep_alive flag is set...
+ if (m_keepalive && m_client && m_client->m_waiting == 0)
{
- if (m_client->m_waiting == 2)
- abort();
+ yaz_log (LOG_LOG, "shutdown (client to proxy) keepalive %s",
+ m_client->get_hostname());
+ assert (m_client->m_waiting != 2);
// Tell client (if any) that no server connection is there..
m_client->m_server = 0;
- yaz_log (LOG_LOG, "shutdown (client to proxy) keepalive %s", m_client->get_hostname());
}
else if (m_client)
{
- if (m_client->m_waiting == 2)
- abort();
- yaz_log (LOG_LOG, "shutdown (client to proxy) close %s", m_client->get_hostname());
+ yaz_log (LOG_LOG, "shutdown (client to proxy) close %s",
+ m_client->get_hostname());
+ assert (m_client->m_waiting != 2);
delete m_client;
}
else if (!m_parent)
{
yaz_log (LOG_LOG, "shutdown (client to proxy) bad state");
- abort();
+ assert (m_parent);
}
else
{
m_waiting = 2; // for debugging purposes only.
odr_destroy(m_init_odr);
delete m_last_query;
+ xfree (m_last_resultSetId);
}
void Yaz_Proxy::timeoutNotify()
m_prev = 0;
m_init_flag = 0;
m_last_query = 0;
+ m_last_resultSetId = 0;
m_last_resultCount = 0;
m_last_ok = 0;
m_sr_transform = 0;
yaz_log (LOG_LOG, "Sending %s to client", apdu_name(apdu));
m_server->send_Z_PDU(apdu);
}
+ if (apdu->which == Z_APDU_close)
+ {
+ shutdown();
+ }
}