<session>2044502273</session>
</init>
+ping
+
+Keeps a session alive. An idle session will time out after one minute. The
+ping command can be used to keep the session alive absent other activity. It
+is suggested that any browser client have a simple alarm handler which
+sends a ping every 50 seconds or so once a session has been initialized.
+
+Example:
+
+search.pz?command=ping&session=2044502273
+
+Response example:
+
+<ping>
+ <status>OK</status>
+</ping>
+
search
Launches a search, parameters:
Short term:
-Structured target profiles -- Zeerex?
+Structured target profiles -- Zeerex? -- requires libxml
Normalization of records -- test if libXSLT is fast enough to:
-- Extract Subject headings, titles, dates, authors for facets and display
-- Merge keys for relevance ranking, etc.
-- Also normalize to UTF-8.
-Implement timeout of sessions, so they don't sit there forever (simple).
Factor Z39.50 stuff out from pazpar2.c to separate file to make room for
later SRU implementation.
Sort by title, date, author. Parameter to 'show' webservice command.
-Additional facets. At least do 'author'.. think about making it general.
+Additional facets. At least do 'author'.. think about making it general. -- libxml
Support for 'blocking' requests, at least for record display before first records
are retrieved (to reduce polling).
Implement detection of 'search complete', so client knows when to stop polling.
-Full record retrieval.
+Full record retrieval. -- libxml
Implement hitsbytarget function to emulate traditional LOT-style U/I
Longer term:
*/
/*
- * $Id: eventl.c,v 1.1 2006-11-14 20:44:37 quinn Exp $
+ * $Id: eventl.c,v 1.2 2006-12-12 02:36:24 quinn Exp $
* Based on revision YAZ' server/eventl.c 1.29.
*/
max = 0;
for (p = *iochans; p; p = p->next)
{
+ if (p->fd < 0)
+ continue;
if (p->force_event)
timeout = &nullto; /* polling select */
if (p->flags & EVENT_INPUT)
time_t now = time(0);
p->force_event = 0;
+ if (!p->destroyed && ((p->max_idle && now - p->last_event >
+ p->max_idle) || force_event == EVENT_TIMEOUT))
+ {
+ p->last_event = now;
+ (*p->fun)(p, EVENT_TIMEOUT);
+ }
+ if (p->fd < 0)
+ continue;
if (!p->destroyed && (FD_ISSET(p->fd, &in) ||
force_event == EVENT_INPUT))
{
p->last_event = now;
(*p->fun)(p, EVENT_EXCEPT);
}
- if (!p->destroyed && ((p->max_idle && now - p->last_event >
- p->max_idle) || force_event == EVENT_TIMEOUT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_TIMEOUT);
- }
}
for (p = *iochans; p; p = nextp)
{
while (*iochans);
return 0;
}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: eventl.h,v $
- * Revision 1.2 2006-11-18 05:00:38 quinn
+ * Revision 1.3 2006-12-12 02:36:24 quinn
+ * Implemented session timeout; ping command
+ *
+ * Revision 1.2 2006/11/18 05:00:38 quinn
* Added record retrieval, etc.
*
* Revision 1.1.1.1 2006/11/14 20:44:38 quinn
#define iochan_setevent(i, e) ((i)->force_event = (e))
#define iochan_getnext(i) ((i)->next)
#define iochan_settimeout(i, t) ((i)->max_idle = (t), (i)->last_event = time(0))
+#define iochan_activity(i) ((i)->last_event = time(0))
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags);
int event_loop(IOCHAN *iochans);
enum
{
Http_Idle,
- Http_Busy // Don't process new HTTP requests
+ Http_Busy // Don't process new HTTP requests while we're busy
} state;
NMEM nmem;
WRBUF wrbuf;
/*_response(c, rs);
- * $Id: http_command.c,v 1.7 2006-12-08 21:40:58 quinn Exp $
+ * $Id: http_command.c,v 1.8 2006-12-12 02:36:24 quinn Exp $
*/
#include <stdio.h>
#include "http.h"
#include "http_command.h"
+extern struct parameters global_parameters;
+extern IOCHAN channel_list;
+
struct http_session {
+ IOCHAN timeout_iochan; // NOTE: This is NOT associated with a socket
struct session *psession;
int session_id;
int timestamp;
static struct http_session *session_list = 0;
+void http_session_destroy(struct http_session *s);
+
+static void session_timeout(IOCHAN i, int event)
+{
+ struct http_session *s = iochan_getdata(i);
+ http_session_destroy(s);
+}
+
struct http_session *http_session_create()
{
struct http_session *r = xmalloc(sizeof(*r));
r->timestamp = 0;
r->next = session_list;
session_list = r;
+ r->timeout_iochan = iochan_create(-1, session_timeout, 0);
+ iochan_setdata(r->timeout_iochan, r);
+ iochan_settimeout(r->timeout_iochan, global_parameters.session_timeout);
+ r->timeout_iochan->next = channel_list;
+ channel_list = r->timeout_iochan;
return r;
}
*p = (*p)->next;
break;
}
- session_destroy(s->psession);
+ iochan_destroy(s->timeout_iochan);
+ destroy_session(s->psession);
xfree(s);
}
id = atoi(session);
for (p = session_list; p; p = p->next)
if (id == p->session_id)
+ {
+ iochan_activity(p->timeout_iochan);
return p;
+ }
error(rs, "417", "Session does not exist, or it has expired", 0);
return 0;
}
exit(0);
}
+
static void cmd_init(struct http_channel *c)
{
int sesid;
http_send_response(c);
}
+static void cmd_ping(struct http_channel *c)
+{
+ struct http_request *rq = c->request;
+ struct http_response *rs = c->response;
+ struct http_session *s = locate_session(rq, rs);
+ if (!s)
+ return;
+ rs->payload = "<ping><status>OK</status></ping>";
+ http_send_response(c);
+}
+
static void cmd_search(struct http_channel *c)
{
struct http_request *rq = c->request;
} commands[] = {
{ "init", cmd_init },
{ "stat", cmd_stat },
-#ifdef GAGA
- { "load", cmd_load },
-#endif
{ "bytarget", cmd_bytarget },
{ "show", cmd_show },
{ "search", cmd_search },
{ "termlist", cmd_termlist },
{ "exit", cmd_exit },
+ { "ping", cmd_ping },
{0,0}
};
-/* $Id: pazpar2.c,v 1.11 2006-12-08 21:40:58 quinn Exp $ */;
+/* $Id: pazpar2.c,v 1.12 2006-12-12 02:36:24 quinn Exp $ */;
#include <stdlib.h>
#include <stdio.h>
#include <yaz/readconf.h>
#include <yaz/pquery.h>
#include <yaz/yaz-util.h>
-#include <yaz/ccl.h>
-#include <yaz/yaz-ccl.h>
#include "pazpar2.h"
#include "eventl.h"
"Client_Stopped"
};
-static struct parameters {
- int timeout; /* operations timeout, in seconds */
- char implementationId[128];
- char implementationName[128];
- char implementationVersion[128];
- int target_timeout; // seconds
- int toget;
- int chunk;
- CCL_bibset ccl_filter;
- yaz_marc_t yaz_marc;
- ODR odr_out;
- ODR odr_in;
-} global_parameters =
+struct parameters global_parameters =
{
30,
"81",
"Index Data PazPar2 (MasterKey)",
PAZPAR2_VERSION,
600, // 10 minutes
+ 60,
100,
MAX_CHUNK,
0,
cc->next = c->next;
}
if (c->connection)
- connection_destroy(c->connection);
+ connection_release(c->connection);
c->next = client_freelist;
client_freelist = c;
}
return 0;
}
+void destroy_session(struct session *s)
+{
+ yaz_log(YLOG_LOG, "Destroying session");
+ while (s->clients)
+ client_destroy(s->clients);
+ nmem_destroy(s->nmem);
+ wrbuf_free(s->wrbuf, 1);
+}
+
struct session *new_session()
{
struct session *session = xmalloc(sizeof(*session));
return session;
}
-void session_destroy(struct session *s)
-{
- // FIXME do some shit here!!!!
-}
-
struct hitsbytarget *hitsbytarget(struct session *se, int *count)
{
static struct hitsbytarget res[1000]; // FIXME MM
#include <yaz/comstack.h>
#include <yaz/pquery.h>
+#include <yaz/ccl.h>
+#include <yaz/yaz-ccl.h>
#include "termlists.h"
#include "relevance.h"
#include "eventl.h"
int connected;
};
+struct parameters {
+ int timeout; /* operations timeout, in seconds */
+ char implementationId[128];
+ char implementationName[128];
+ char implementationVersion[128];
+ int target_timeout; // seconds
+ int session_timeout;
+ int toget;
+ int chunk;
+ CCL_bibset ccl_filter;
+ yaz_marc_t yaz_marc;
+ ODR odr_out;
+ ODR odr_in;
+};
+
struct hitsbytarget *hitsbytarget(struct session *s, int *count);
int select_targets(struct session *se);
struct session *new_session();
-void session_destroy(struct session *s);
+void destroy_session(struct session *s);
int load_targets(struct session *s, const char *fn);
void statistics(struct session *s, struct statistics *stat);
char *search(struct session *s, char *query);