From: Adam Dickmeiss Date: Tue, 12 Sep 2000 12:09:53 +0000 (+0000) Subject: More work on high-level server. X-Git-Tag: YAZPP.0.3~77 X-Git-Url: http://git.indexdata.com/?p=yazpp-moved-to-github.git;a=commitdiff_plain;h=35cfa3b3d2c9b8adb8c4bfd4c95620929e35466b More work on high-level server. --- diff --git a/include/yaz-pdu-assoc.h b/include/yaz-pdu-assoc.h index 3ff7ff5..7fa10ab 100644 --- a/include/yaz-pdu-assoc.h +++ b/include/yaz-pdu-assoc.h @@ -2,7 +2,7 @@ * Copyright (c) 1998-2000, Index Data. * See the file LICENSE for details. * - * $Id: yaz-pdu-assoc.h,v 1.8 2000-09-08 10:23:42 adam Exp $ + * $Id: yaz-pdu-assoc.h,v 1.9 2000-09-12 12:09:53 adam Exp $ */ #include @@ -44,7 +44,7 @@ class YAZ_EXPORT Yaz_PDU_Assoc : public IYaz_PDU_Observable, IYazSocketObserver /// Create object using specified socketObservable Yaz_PDU_Assoc(IYazSocketObservable *socketObservable); /// Close socket and destroy object. - virtual ~Yaz_PDU_Assoc(); + /// virtual ~Yaz_PDU_Assoc(); /// Clone the object IYaz_PDU_Observable *clone(); /// Send PDU diff --git a/include/yaz-z-server.h b/include/yaz-z-server.h index 3a5cf01..53502ae 100644 --- a/include/yaz-z-server.h +++ b/include/yaz-z-server.h @@ -2,7 +2,7 @@ * Copyright (c) 2000, Index Data. * See the file LICENSE for details. * - * $Id: yaz-z-server.h,v 1.1 2000-09-08 10:23:42 adam Exp $ + * $Id: yaz-z-server.h,v 1.2 2000-09-12 12:09:53 adam Exp $ */ #include @@ -11,6 +11,26 @@ class YAZ_EXPORT Yaz_Z_Server : public Yaz_Z_Assoc { public: Yaz_Z_Server(IYaz_PDU_Observable *the_PDU_Observable); virtual void recv_Z_PDU(Z_APDU *apdu); -private: - int m_no; + virtual void recv_Z_init (Z_InitRequest *initRequest, + Z_InitResponse *initResponse) = 0; + virtual void recv_Z_search (Z_SearchRequest *searchRequest, + Z_SearchResponse *searchResponse) = 0; + virtual void recv_Z_present (Z_PresentRequest *presentRequest, + Z_PresentResponse *presentResponse) = 0; + virtual void recv_Z_record (const char *resultSetName, + int position, + int *format, + Z_RecordComposition *comp, + Z_NamePlusRecord *namePlusRecord, + Z_DefaultDiagFormat *diagnostics) = 0; + private: + Z_Records *pack_records (const char *resultSetName, + int start, int *num, + Z_RecordComposition *comp, + int *next, int *pres, + int *oid); + void piggyback (Z_SearchRequest *searchRequest, + Z_SearchResponse *searchResponse); + int m_preferredMessageSize; + int m_maximumRecordSize; }; diff --git a/src/yaz-pdu-assoc.cpp b/src/yaz-pdu-assoc.cpp index ae8bfaf..084c4e9 100644 --- a/src/yaz-pdu-assoc.cpp +++ b/src/yaz-pdu-assoc.cpp @@ -3,7 +3,10 @@ * See the file LICENSE for details. * * $Log: yaz-pdu-assoc.cpp,v $ - * Revision 1.13 2000-09-08 10:23:42 adam + * Revision 1.14 2000-09-12 12:09:53 adam + * More work on high-level server. + * + * Revision 1.13 2000/09/08 10:23:42 adam * Added skeleton of yaz-z-server. * * Revision 1.12 2000/09/06 14:23:45 adam @@ -30,7 +33,7 @@ * Revision 1.6 1999/04/20 10:30:05 adam * Implemented various stuff for client and proxy. Updated calls * to ODR to reflect new name parameter. - * + *g * Revision 1.5 1999/04/09 11:46:57 adam * Added object Yaz_Z_Assoc. Much more functional client. * @@ -79,11 +82,6 @@ IYaz_PDU_Observable *Yaz_PDU_Assoc::clone() return copy; } -Yaz_PDU_Assoc::~Yaz_PDU_Assoc() -{ - destroy(); -} - void Yaz_PDU_Assoc::socketNotify(int event) { logf (m_log, "Yaz_PDU_Assoc::socketNotify p=%p event = %d", this, event); @@ -131,7 +129,6 @@ void Yaz_PDU_Assoc::socketNotify(int event) } if (!(new_line = cs_accept(m_cs))) return; - /* 1. create socket-manager 2. create pdu-assoc 3. create top-level object @@ -139,6 +136,7 @@ void Yaz_PDU_Assoc::socketNotify(int event) 4. start thread */ int fd = cs_fileno(new_line); + logf (m_log, "accept ok fd = %d", fd); cs_fileno(new_line) = -1; cs_close (new_line); /* potential problem ... */ #if 1 @@ -349,6 +347,7 @@ void Yaz_PDU_Assoc::listen(IYaz_PDU_Observer *observer, m_socketObservable->addObserver(cs_fileno(cs), this); m_socketObservable->maskObserver(this, YAZ_SOCKET_OBSERVE_READ| YAZ_SOCKET_OBSERVE_EXCEPT); + logf (m_log, "Yaz_PDU_Assoc::listen ok fd=%d", cs_fileno(cs)); m_state = Listen; } @@ -398,7 +397,7 @@ void Yaz_PDU_Assoc::socket(IYaz_PDU_Observer *observer, int fd) } } -#if 0 +#if 1 // Single-threaded... Only useful for non-blocking handlers void Yaz_PDU_Assoc::childNotify(int fd) diff --git a/src/yaz-server.cpp b/src/yaz-server.cpp index 8aecb14..1d894a1 100644 --- a/src/yaz-server.cpp +++ b/src/yaz-server.cpp @@ -3,7 +3,10 @@ * See the file LICENSE for details. * * $Log: yaz-server.cpp,v $ - * Revision 1.8 2000-09-08 10:23:42 adam + * Revision 1.9 2000-09-12 12:09:53 adam + * More work on high-level server. + * + * Revision 1.8 2000/09/08 10:23:42 adam * Added skeleton of yaz-z-server. * * Revision 1.7 1999/12/06 13:52:45 adam @@ -40,7 +43,19 @@ class MyServer : public Yaz_Z_Server { public: MyServer(IYaz_PDU_Observable *the_PDU_Observable); - void recv_Z_PDU(Z_APDU *apdu); + void recv_Z_init (Z_InitRequest *initRequest, + Z_InitResponse *initResponse); + void recv_Z_search (Z_SearchRequest *searchRequest, + Z_SearchResponse *searchResponse); + void recv_Z_present (Z_PresentRequest *presentRequest, + Z_PresentResponse *presentResponse); + + void recv_Z_record (const char *resultSetName, + int position, + int *format, + Z_RecordComposition *comp, + Z_NamePlusRecord *namePlusRecord, + Z_DefaultDiagFormat *diagnostics); IYaz_PDU_Observer* clone(IYaz_PDU_Observable *the_PDU_Observable); void failNotify(); void timeoutNotify(); @@ -51,28 +66,34 @@ private: static int stop = 0; -void MyServer::recv_Z_PDU(Z_APDU *apdu) +void MyServer::recv_Z_init (Z_InitRequest *initRequest, + Z_InitResponse *initResponse) { - logf (LOG_LOG, "recv_Z_PDU"); - switch (apdu->which) - { - case Z_APDU_initRequest: - logf (LOG_LOG, "got InitRequest"); - apdu = create_Z_PDU(Z_APDU_initResponse); - send_Z_PDU(apdu); - break; - case Z_APDU_searchRequest: - logf (LOG_LOG, "got searchRequest"); - apdu = create_Z_PDU(Z_APDU_searchResponse); - send_Z_PDU(apdu); - break; - case Z_APDU_presentRequest: - logf (LOG_LOG, "got presentRequest"); - apdu = create_Z_PDU(Z_APDU_presentResponse); - send_Z_PDU(apdu); - // stop = 1; - break; - } + logf (LOG_LOG, "MyServer::recv_Z_init"); +} + +void MyServer::recv_Z_search (Z_SearchRequest *searchRequest, + Z_SearchResponse *searchResponse) +{ + logf (LOG_LOG, "MyServer::recv_Z_search"); + delete this; + stop = 1; +} + +void MyServer::recv_Z_present (Z_PresentRequest *presentRequest, + Z_PresentResponse *presentResponse) +{ + logf (LOG_LOG, "MyServer::recv_Z_present"); +} + +void MyServer::recv_Z_record (const char *resultSetName, + int position, + int *format, + Z_RecordComposition *comp, + Z_NamePlusRecord *namePlusRecord, + Z_DefaultDiagFormat *diagnostics) +{ + } IYaz_PDU_Observer *MyServer::clone(IYaz_PDU_Observable *the_PDU_Observable) @@ -109,19 +130,25 @@ void MyServer::connectNotify() int main(int argc, char **argv) { - Yaz_SocketManager mySocketManager; - Yaz_PDU_Assoc *my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager); - - MyServer z(my_PDU_Assoc); - - if (argc <= 1) - z.server("@:9999"); - else + while (1) { - for (int i = 1; i < argc; i++) - z.server(argv[i]); + stop = 0; + Yaz_SocketManager mySocketManager; + Yaz_PDU_Assoc *my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager); + + MyServer *z = new MyServer(my_PDU_Assoc); + + if (argc <= 1) + z->server("@:9999"); + else + { + for (int i = 1; i < argc; i++) + z->server(argv[i]); + } + while (!stop && mySocketManager.processEvent() > 0) + ; + logf (LOG_LOG, "bailing out"); + delete z; } - while (!stop && mySocketManager.processEvent() > 0) - ; return 0; } diff --git a/src/yaz-z-server.cpp b/src/yaz-z-server.cpp index 993a6d6..ddc0bf0 100644 --- a/src/yaz-z-server.cpp +++ b/src/yaz-z-server.cpp @@ -3,7 +3,10 @@ * See the file LICENSE for details. * * $Log: yaz-z-server.cpp,v $ - * Revision 1.1 2000-09-08 10:23:42 adam + * Revision 1.2 2000-09-12 12:09:53 adam + * More work on high-level server. + * + * Revision 1.1 2000/09/08 10:23:42 adam * Added skeleton of yaz-z-server. * */ @@ -15,11 +18,263 @@ Yaz_Z_Server::Yaz_Z_Server(IYaz_PDU_Observable *the_PDU_Observable) : Yaz_Z_Assoc(the_PDU_Observable) { - m_no = 0; } -void Yaz_Z_Server::recv_Z_PDU (Z_APDU *apdu) +Z_Records *Yaz_Z_Server::pack_records (const char *resultSetName, + int start, int *num, + Z_RecordComposition *comp, + int *next, int *pres, + int *format) +{ +#if 0 + int recno, total_length = 0, toget = *num, dumped_records = 0; + Z_Records *records = + (Z_Records *) odr_malloc (odr_encode(), sizeof(*records)); + Z_NamePlusRecordList *reclist = + (Z_NamePlusRecordList *) odr_malloc (odr_encode(), sizeof(*reclist)); + Z_NamePlusRecord **list = + (Z_NamePlusRecord **) odr_malloc (odr_encode(), sizeof(*list) * toget); + + records->which = Z_Records_DBOSD; + records->u.databaseOrSurDiagnostics = reclist; + reclist->num_records = 0; + reclist->records = list; + *pres = Z_PRES_SUCCESS; + *num = 0; + *next = 0; + + yaz_log(LOG_LOG, "Request to pack %d+%d", start, toget); + yaz_log(LOG_DEBUG, "pms=%d, mrs=%d", m_preferredMessageSize, + m_maximumRecordSize); + for (recno = start; reclist->num_records < toget; recno++) + { + Z_NamePlusRecord *rec = + (Z_NamePlusRecord *) odr_malloc (odr_encode(), sizeof(*rec)); + rec->databaseName = 0; + rec->which = Z_NamePlusRecord_databaseRecord; + rec->u.databaseRecord = 0; + + Z_DefaultDiagFormat *diagnostics = (Z_DefaultDiagFormat *) + odr_malloc (odr_encode(), sizeof(*diagnostics)); + diagnostics->diagnosticSetId = 0; + diagnostics->condition = 0; + diagnostics->which = Z_DefaultDiagFormat_v2Addinfo; + + recv_Z_record (resultSetName, recno, format, comp, rec, diagnostics); + + bend_fetch_rr freq; + Z_NamePlusRecord *thisrec; + int this_length = 0; + /* + * we get the number of bytes allocated on the stream before any + * allocation done by the backend - this should give us a reasonable + * idea of the total size of the data so far. + */ + total_length = odr_total(a->encode) - dumped_records; + freq.errcode = 0; + freq.errstring = 0; + freq.basename = 0; + freq.len = 0; + freq.record = 0; + freq.last_in_set = 0; + freq.setname = setname; + freq.surrogate_flag = 0; + freq.number = recno; + freq.comp = comp; + freq.request_format = format; + freq.request_format_raw = oid; + freq.output_format = format; + freq.output_format_raw = 0; + freq.stream = a->encode; + freq.print = a->print; + freq.surrogate_flag = 0; + freq.referenceId = referenceId; + (*a->init->bend_fetch)(a->backend, &freq); + /* backend should be able to signal whether error is system-wide + or only pertaining to current record */ + if (freq.errcode) + { + if (!freq.surrogate_flag) + { + *pres = Z_PRES_FAILURE; + return diagrec(a, freq.errcode, freq.errstring); + } + reclist->records[reclist->num_records] = + surrogatediagrec(a, freq.basename, freq.errcode, + freq.errstring); + reclist->num_records++; + *next = freq.last_in_set ? 0 : recno + 1; + continue; + } + if (freq.len >= 0) + this_length = freq.len; + else + this_length = odr_total(a->encode) - total_length; + yaz_log(LOG_DEBUG, " fetched record, len=%d, total=%d", + this_length, total_length); + if (this_length + total_length > a->preferredMessageSize) + { + /* record is small enough, really */ + if (this_length <= a->preferredMessageSize) + { + yaz_log(LOG_DEBUG, " Dropped last normal-sized record"); + *pres = Z_PRES_PARTIAL_2; + break; + } + /* record can only be fetched by itself */ + if (this_length < a->maximumRecordSize) + { + yaz_log(LOG_DEBUG, " Record > prefmsgsz"); + if (toget > 1) + { + yaz_log(LOG_DEBUG, " Dropped it"); + reclist->records[reclist->num_records] = + surrogatediagrec(a, freq.basename, 16, 0); + reclist->num_records++; + *next = freq.last_in_set ? 0 : recno + 1; + dumped_records += this_length; + continue; + } + } + else /* too big entirely */ + { + yaz_log(LOG_DEBUG, "Record > maxrcdsz"); + reclist->records[reclist->num_records] = + surrogatediagrec(a, freq.basename, 17, 0); + reclist->num_records++; + *next = freq.last_in_set ? 0 : recno + 1; + dumped_records += this_length; + continue; + } + } + + if (!(thisrec = (Z_NamePlusRecord *) + odr_malloc(a->encode, sizeof(*thisrec)))) + return 0; + if (!(thisrec->databaseName = (char *)odr_malloc(a->encode, + strlen(freq.basename) + 1))) + return 0; + strcpy(thisrec->databaseName, freq.basename); + thisrec->which = Z_NamePlusRecord_databaseRecord; + + if (freq.output_format_raw) + { + struct oident *ident = oid_getentbyoid(freq.output_format_raw); + freq.output_format = ident->value; + } + thisrec->u.databaseRecord = z_ext_record(a->encode, freq.output_format, + freq.record, freq.len); + if (!thisrec->u.databaseRecord) + return 0; + reclist->records[reclist->num_records] = thisrec; + reclist->num_records++; + *next = freq.last_in_set ? 0 : recno + 1; + } + *num = reclist->num_records; + return records; +#endif + return 0; +} + +void Yaz_Z_Server::piggyback (Z_SearchRequest *req, + Z_SearchResponse *res) { - logf (LOG_LOG, "recv_Z_PDU in Yaz_Z_Server"); + bool_t *sr = (bool_t *)odr_malloc (odr_encode(), sizeof(*sr)); + *sr = 1; + + int *next = (int *)odr_malloc (odr_encode(), sizeof(*next)); + *next = 0; + + int *toget = (int *)odr_malloc (odr_encode(), sizeof(*toget)); + *toget = 0; + + int *presst = (int *)odr_malloc (odr_encode(), sizeof(*presst)); + *presst = 0; + + Z_RecordComposition comp, *compp = 0; + int hits = *res->resultCount; + + int *nulint = (int *)odr_malloc (odr_encode(), sizeof(*nulint)); + *nulint = 0; + + res->records = 0; + + comp.which = Z_RecordComp_simple; + /* how many records does the user agent want, then? */ + if (hits <= *req->smallSetUpperBound) + { + *toget = hits; + if ((comp.u.simple = req->smallSetElementSetNames)) + compp = ∁ + } + else if (hits < *req->largeSetLowerBound) + { + *toget = *req->mediumSetPresentNumber; + if (*toget > hits) + *toget = hits; + if ((comp.u.simple = req->mediumSetElementSetNames)) + compp = ∁ + } + else + *toget = 0; + + if (*toget && !res->records) + { + res->records = + pack_records(req->resultSetName, 1, + toget, compp, next, presst, + req->preferredRecordSyntax); + if (!res->records) + return; + res->numberOfRecordsReturned = toget; + res->nextResultSetPosition = next; + res->searchStatus = sr; + res->resultSetStatus = 0; + res->presentStatus = presst; + } + else + { + if (hits) + *next = 1; + res->numberOfRecordsReturned = nulint; + res->nextResultSetPosition = next; + res->searchStatus = sr; + res->resultSetStatus = 0; + res->presentStatus = 0; + } +} + +void Yaz_Z_Server::recv_Z_PDU (Z_APDU *apdu_request) +{ + Z_APDU *apdu_response; + switch (apdu_request->which) + { + case Z_APDU_initRequest: + logf (LOG_LOG, "got InitRequest"); + apdu_response = create_Z_PDU(Z_APDU_initResponse); + recv_Z_init (apdu_request->u.initRequest, + apdu_response->u.initResponse); + send_Z_PDU(apdu_response); + break; + case Z_APDU_searchRequest: + logf (LOG_LOG, "got SearchRequest"); + apdu_response = create_Z_PDU(Z_APDU_searchResponse); + recv_Z_search (apdu_request->u.searchRequest, + apdu_response->u.searchResponse); + if (!apdu_response->u.searchResponse->records) + { + piggyback(apdu_request->u.searchRequest, + apdu_response->u.searchResponse); + } + send_Z_PDU(apdu_response); + break; + case Z_APDU_presentRequest: + logf (LOG_LOG, "got PresentRequest"); + apdu_response = create_Z_PDU(Z_APDU_presentResponse); + recv_Z_present (apdu_request->u.presentRequest, + apdu_response->u.presentResponse); + send_Z_PDU(apdu_response); + break; + } }