polling after a search. Implemented in 'test1' interface.
session
start -- 0-indexed!!
num -- default=20
+block -- 0 or 1
+
+If block is set, the command will hang until there are records ready
+to display. Use this to show first records rapidly without requiring rapid
+polling.
Example:
later SRU implementation.
Sort by title, date, author. Parameter to 'show' webservice command.
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. -- libxml
Implement hitsbytarget function to emulate traditional LOT-style U/I
-/*_response(c, rs);
- * $Id: http_command.c,v 1.8 2006-12-12 02:36:24 quinn Exp $
+/*
+ * $Id: http_command.c,v 1.9 2006-12-17 13:42:47 quinn Exp $
*/
#include <stdio.h>
struct http_session {
IOCHAN timeout_iochan; // NOTE: This is NOT associated with a socket
struct session *psession;
- int session_id;
+ unsigned int session_id;
int timestamp;
struct http_session *next;
};
http_send_response(c);
}
-int make_sessionid()
+unsigned int make_sessionid()
{
struct timeval t;
- int res;
+ unsigned int res;
static int seq = 0;
seq++;
if (gettimeofday(&t, 0) < 0)
abort();
res = t.tv_sec;
- res = (res << 8) | (seq & 0xff);
+ res = ((res << 8) | (seq & 0xff)) & ((unsigned int) (1 << 31) - 1);
return res;
}
{
struct http_session *p;
char *session = http_argbyname(rq, "session");
- int id;
+ unsigned int id;
if (!session)
{
static void cmd_init(struct http_channel *c)
{
- int sesid;
+ unsigned int sesid;
char buf[1024];
struct http_session *s = http_session_create();
struct http_response *rs = c->response;
- // FIXME create a pazpar2 session
yaz_log(YLOG_DEBUG, "HTTP Session init");
sesid = make_sessionid();
s->session_id = sesid;
- sprintf(buf, "<init><status>OK</status><session>%d</session></init>", sesid);
+ sprintf(buf, "<init><status>OK</status><session>%u</session></init>", sesid);
rs->payload = nmem_strdup(c->nmem, buf);
http_send_response(c);
}
http_send_response(c);
}
-static void cmd_show(struct http_channel *c)
+static void show_records(struct http_channel *c)
{
struct http_request *rq = c->request;
struct http_response *rs = c->response;
http_send_response(c);
}
+static void show_records_ready(void *data)
+{
+ struct http_channel *c = (struct http_channel *) data;
+
+ show_records(c);
+}
+
+static void cmd_show(struct http_channel *c)
+{
+ struct http_request *rq = c->request;
+ struct http_response *rs = c->response;
+ struct http_session *s = locate_session(rq, rs);
+ char *block = http_argbyname(rq, "block");
+
+ if (!s)
+ return;
+
+ if (block)
+ {
+ if (!s->psession->reclist || !s->psession->reclist->num_records)
+ {
+ session_set_watch(s->psession, SESSION_WATCH_RECORDS, show_records_ready, c);
+ yaz_log(YLOG_DEBUG, "Blocking on cmd_show");
+ return;
+ }
+ }
+
+ show_records(c);
+}
+
static void cmd_ping(struct http_channel *c)
{
struct http_request *rq = c->request;
-/* $Id: pazpar2.c,v 1.13 2006-12-14 14:58:03 quinn Exp $ */;
+/* $Id: pazpar2.c,v 1.14 2006-12-17 13:42:47 quinn Exp $ */;
#include <stdlib.h>
#include <stdio.h>
static void connection_destroy(struct connection *co);
static int client_prep_connection(struct client *cl);
static void ingest_records(struct client *cl, Z_Records *r);
+void session_alert_watch(struct session *s, int what);
-IOCHAN channel_list = 0; // Master list of connections we're listening to.
+IOCHAN channel_list = 0; // Master list of connections we're handling events to
static struct connection *connection_freelist = 0;
static struct client *client_freelist = 0;
static void ingest_records(struct client *cl, Z_Records *r)
{
struct record *rec;
+ struct session *s = cl->session;
Z_NamePlusRecordList *rlist;
int i;
if (!rec)
continue;
}
+ if (s->watchlist[SESSION_WATCH_RECORDS].fun && rlist->num_records)
+ session_alert_watch(s, SESSION_WATCH_RECORDS);
}
static void do_presentResponse(IOCHAN i, Z_APDU *a)
s->watchlist[what].data = data;
}
+void session_alert_watch(struct session *s, int what)
+{
+ if (!s->watchlist[what].fun)
+ return;
+ (*s->watchlist[what].fun)(s->watchlist[what].data);
+ s->watchlist[what].fun = 0;
+ s->watchlist[what].data = 0;
+}
+
// This should be extended with parameters to control selection criteria
// Associates a set of clients with a session;
int select_targets(struct session *se)
var xml = xshow.responseXML;
var body = document.getElementById("body");
var hits = xml.getElementsByTagName("hit");
- if (!hits[0])
+ if (!hits[0]) // We should never get here with blocking operations
{
body.innerHTML = "No records yet";
searchtimer = setTimeout(check_search, 250);
}
shown++;
if (shown < 5)
- searchtimer = setTimeout(check_search, 400);
- else if (shown < 10)
searchtimer = setTimeout(check_search, 1000);
else
- searchtimer = setTimeout(check_search, 4000);
+ searchtimer = setTimeout(check_search, 2000);
}
+ if (!termtimer)
+ termtimer = setTimeout(check_termlist, 1000);
}
function check_search()
var url = "search.pz2?" +
"command=show" +
"&start=" + startrec +
- "&session=" + session;
+ "&session=" + session +
+ "&block=1";
xshow = GetXmlHttpObject();
xshow.onreadystatechange=show_records;
xshow.open("GET", url);
alert(msg);
return;
}
- searchtimer = setTimeout(check_search, 250);
- termtimer = setTimeout(check_termlist, 1000);
+ check_search();
stattimer = setTimeout(check_stat, 1000);
}
function start_search()
{
clearTimeout(termtimer);
+ termtimer = 0;
clearTimeout(searchtimer);
+ searchtimer = 0;
clearTimeout(stattimer);
+ stattimer = 0;
clearTimeout(showtimer);
+ showtimer = 0;
if (!targets_loaded)
{
alert("Please load targets first");