Update of /cvsroot/monetdb/pathfinder/runtime
In directory sc8-pr-cvs16:/tmp/cvs-serv2946
Modified Files:
pathfinder.mx xrpc_client.mx xrpc_server.mx
Log Message:
- Better error handling: create a buffer to store MIL error messages.
When xquery_method() returns the vague error message "xquery_method:
error during execution", copy the real MIL errors from the buffer into
the SOAP Fault message.
- Upon receiving the response message for an updating RPC call,
check if it contains a SOAP Fault message and handle it accordingly.
Index: xrpc_client.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_client.mx,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- xrpc_client.mx 17 Apr 2007 13:37:52 -0000 1.29
+++ xrpc_client.mx 18 Apr 2007 19:50:26 -0000 1.30
@@ -150,7 +150,10 @@
fault_text_pre :=
pre_prop.ord_select(fault_text_pre).reverse().fetch(0);
fault_text_pre := pre_prop.fetch(int(fault_text_pre)+1);
var fault_text := prop_text.fetch(fault_text_pre);
- ERROR("SOAP Fault Code : %s\nSOAP Fault Reason: %s\n",
fault_value, fault_text);
+ ERROR("Remote execution failed.\n" +
+ "SOAP Fault Code: %s\n" +
+ "SOAP Fault Reason:\n%s\n",
+ fault_value, fault_text);
}
}
@@ -638,28 +641,6 @@
}
/**
- * NOTE: this function is not used any more, as of Dec 06, 2006
- * @return cont-kind, or
- * GDK_int_min by error
- */
-/*
-static int
-getContKind(BAT *itemBat, BAT *kindBat, int offset)
-{
- BUN bres;
- oid index = *(oid*)BUNhead(itemBat, BUNptr(itemBat, offset));
-
- BUNfndVOID(bres, kindBat, &index);
- if(!bres){
- GDKerror("getContKind: could not find BUN with head value "
- "[EMAIL PROTECTED]", index);
- return GDK_int_min;
- }
- return *(int*) BUNtail(kindBat, bres);
-}
-*/
-
-/**
* @return WS BAT, or
* NULL by error
*/
@@ -741,6 +722,46 @@
return ret;
}
+static void
+handle_soap_fault_msg(char *errmsg)
+{
+ char *strptr, *strptr2;
+
+ strptr = strstr(errmsg, "<env:Value");
+ if(!strptr) {
+ GDKerror("handle_soap_fault_msg: SOAP Fault message not "
+ "well-formed: could not find \"<env:Value\".\n%s\n",
+ errmsg);
+ }
+ strptr = strchr(strptr, '>'); assert(strptr);
+ strptr2 = strstr(++strptr, "</env:Value>");
+ if( (!strptr) || (!strptr2) ) {
+ GDKerror("handle_soap_fault_msg: SOAP Fault message not "
+ "well-formed at \"<env:Value>.\n%s\n", errmsg);
+ return;
+ }
+ strptr2[0] = '\0';
+ GDKerror("SOAP Fault Code : %s\n", strptr);
+ strptr2[0] = '<';
+
+ strptr = strstr(strptr2+12, "<env:Text");
+ if(!strptr) {
+ GDKerror("handle_soap_fault_msg: SOAP Fault message not "
+ "well-formed: could not find \"<env:Text\".\n%s\n",
+ errmsg);
+ return;
+ }
+ strptr = strchr(strptr, '>') + 1;
+ strptr2 = strstr(strptr, "</env:Text>");
+ if( (!strptr) || (!strptr2) ) {
+ GDKerror("handle_soap_fault_msg: SOAP Fault message not "
+ "well-formed at \"<env:Text>\".\n%s\n", errmsg);
+ return;
+ }
+ strptr2[0] = '\0';
+ GDKerror("SOAP Fault Reason:\n%s\n", strptr);
+}
+
/**
* try to receive the response message and shred it into shredBAT
* Returns shredBAT, or
@@ -753,30 +774,28 @@
int updCall,
lng *time_xrpcClntDeSeria)
{
- char *strptr = NULL, *ptr = NULL;
+ char *strptr = NULL;
int ret;
stream *in;
BAT *shredBAT;
- in = socket_rastream(sock, "http_receive");
- if(!in){
+ if( !(in = socket_rastream(sock, "http_receive")) ){
GDKerror("response2bat: failed to create socket_rastream\n");
return NULL;
}
b->pos = 0;
errno = 0;
- ret = stream_readline(in, b->buf, 1024);
- if (ret < 0) {
- GDKerror("response2bat: failed to receive response from %s: %s\n",
- dst, errno?strerror(errno):".");
+ if( !(ret = stream_readline(in, b->buf, 1024)) ){
+ GDKerror("response2bat: failed to receive response from %s", dst);
+ if(errno) GDKerror(": %s", strerror(errno));
+ GDKerror(".\n");
stream_close(in); stream_destroy(in);
return NULL;
}
- strptr = strchr(b->buf, ' ');
- if (!strptr) {
- GDKerror("response2bat: invalid response from %s\n%s\n",
+ if( !(strptr = strchr(b->buf, ' ')) ){
+ GDKerror("response2bat: invalid response from %s:\n%s\n",
dst, b->buf);
stream_close(in); stream_destroy(in);
return NULL;
@@ -785,55 +804,22 @@
if (strncmp(++strptr, "200", 3) != 0) {
b->buf[ret] = '\0';
GDKerror("HTTP Error Code : %s\n", b->buf + 9);
- strptr = b->buf + b->pos + 1;
- do{ /* receive the whole error message */
+
+ b->pos = 0;
+ do{ /* read the SOAP Fault message */
errno = 0;
ret = stream_read(in, (b->buf + b->pos), 1, (b->len - b->pos));
- b->pos += ret;
+ if (ret > 0) b->pos += ret;
} while (ret > 0);
if (ret < 0) {
- GDKerror("response2bat: failed to receive response from %s: %s\n",
- dst, errno?strerror(errno):".");
- stream_close(in); stream_destroy(in);
+ GDKerror("response2bat: failed to receive response from %s",
+ dst);
+ if(errno) GDKerror(": %s", strerror(errno));
+ GDKerror(".\n");
return NULL;
}
b->buf[b->pos] = 0;
-
- strptr = strstr(strptr, "<env:Value");
- if(!strptr) {
- GDKerror("response2bat: SOAP Fault message not well-formed: "
- "could not find \"<env:Value\".\n");
- stream_close(in); stream_destroy(in);
- return NULL;
- }
- strptr = strchr(strptr, '>') + 1;
- ptr = strstr(strptr, "</env:Value>");
- if( (!strptr) || (!ptr) ) {
- GDKerror("response2bat: SOAP Fault message not well-formed: "
- "could not find \"</env:Value>\".\n");
- stream_close(in); stream_destroy(in);
- return NULL;
- }
- ptr[0] = '\0';
- GDKerror("SOAP Fault Code : %s\n", strptr);
-
- strptr = strstr(ptr+12, "<env:Text");
- if(!strptr) {
- GDKerror("response2bat: SOAP Fault message not well-formed: "
- "could not find \"<env:Text\".\n");
- stream_close(in); stream_destroy(in);
- return NULL;
- }
- strptr = strchr(strptr, '>') + 1;
- ptr = strstr(strptr, "</env:Text>");
- if( (!strptr) || (!ptr) ) {
- GDKerror("response2bat: SOAP Fault message not well-formed: "
- "could not find \"</env:Text>\".\n");
- stream_close(in); stream_destroy(in);
- return NULL;
- }
- ptr[0] = '\0';
- GDKerror("SOAP Fault Reason: %s\n", strptr);
+ handle_soap_fault_msg(b->buf);
stream_close(in); stream_destroy(in);
return NULL;
}
@@ -846,8 +832,10 @@
ret = 0; /* end-of-HTTP-header found */
} while (ret > 0);
if (ret < 0) {
- GDKerror("response2bat: failed to receive response from %s: %s\n",
- dst, errno?strerror(errno):".");
+ GDKerror("response2bat: failed to receive response from %s",
+ dst);
+ if(errno) GDKerror(": %s", strerror(errno));
+ GDKerror(".\n");
stream_close(in); stream_destroy(in);
return NULL;
}
@@ -861,23 +849,34 @@
}
if (updCall) {
- *time_xrpcClntDeSeria = GDKusec() - *time_xrpcClntDeSeria;
+ b->pos = 0;
+ do{ /* Check for error message */
+ errno = 0;
+ ret = stream_read(in, (b->buf + b->pos), 1, (b->len - b->pos));
+ if (ret > 0) b->pos += ret;
+ } while (ret > 0);
+ b->buf[b->pos] = 0;
stream_close(in); stream_destroy(in);
- return shredBAT;
+
+ if(b->pos == 0){ /* no error message => operation succeeded */
+ *time_xrpcClntDeSeria = GDKusec() - *time_xrpcClntDeSeria;
+ return shredBAT;
+ } else {
+ handle_soap_fault_msg(b->buf);
+ BBPreclaim(shredBAT);
+ return NULL;
+ }
}
if(shred(shredBAT, NULL, NULL, in, 0, NULL, NULL, NULL) ==GDK_FAIL) {
- GDKerror("most probably, the XRPC response contains some MIL "
- "error message\n");
- if(BBPreclaim(shredBAT) == -1){
- GDKerror("response2bat: failed to destroy \"shredBAT\"!");
- }
+ GDKerror("response2bat: invalid XRPC response received\n");
+ BBPreclaim(shredBAT);
stream_close(in); stream_destroy(in);
return NULL;
}
+
/* Stop timing Client DeSerialisation */
*time_xrpcClntDeSeria = GDKusec() - *time_xrpcClntDeSeria;
-
stream_close(in); stream_destroy(in);
return shredBAT;
}
Index: pathfinder.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/pathfinder.mx,v
retrieving revision 1.342
retrieving revision 1.343
diff -u -d -r1.342 -r1.343
--- pathfinder.mx 18 Apr 2007 17:41:37 -0000 1.342
+++ pathfinder.mx 18 Apr 2007 19:50:25 -0000 1.343
@@ -4544,7 +4544,7 @@
c = xquery_types[t].loc;
if (xquery_types[t].monet_tpe == TYPE_str) {
- /* we no longer do fancy strTostr for strings; just copied
as-is */
+ /* we no longer do fancy strTostr for strings; just copied as-is */
char *t, *s = argval[l];
int len = strlen(s)*2;
if (len >= ctx->vallen) {
@@ -5854,11 +5854,10 @@
if (err == NULL) {
err = xquery_function_call(ctx, usec, ns, method, argc, itercnt,
argcnt, argtpe, argval, shredBAT);
if (err == (char*) -1) err = "xquery_method: function could not be
resolved.\n";
- else if (err == xquery_nondescriptive_error) err =
xquery_function_error;
+ else if (err == xquery_function_error) err =
xquery_nondescriptive_error;
}
time_xrpcServApp = GDKusec() - time_xrpcServApp;
-
if (flags&1){
/* print timing ourselves */
fprintf(stdout, "\n"
Index: xrpc_server.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_server.mx,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- xrpc_server.mx 18 Apr 2007 11:36:42 -0000 1.36
+++ xrpc_server.mx 18 Apr 2007 19:50:26 -0000 1.37
@@ -234,39 +234,51 @@
BAT* xrpc_trusted = NULL;
BAT* xrpc_admin = NULL;
-#define clean_up(argcnt, argtpe, argval, iterc, nr_args) { \
- lng i = 0; \
- \
- if(argcnt){ \
- for(i = 0; i < iterc; i++) GDKfree(argcnt[i]); \
- GDKfree(argcnt); \
- } \
- if(argtpe){ \
- for(i = 0; i < nr_args; i++) GDKfree(argtpe[i]); \
- GDKfree(argtpe); \
- } \
- if(argval){ \
- for(i = 0; i < nr_args; i++) GDKfree(argval[i]); \
- GDKfree(argval); \
- } \
+static INLINE void
+clean_up(lng **argcnt,
+ char **argtpe,
+ char **argval,
+ lng iterc,
+ lng nr_args)
+{
+ lng i = 0;
+
+ if(argcnt){
+ for(i = 0; i < iterc; i++) GDKfree(argcnt[i]);
+ GDKfree(argcnt);
+ }
+ if(argtpe){
+ for(i = 0; i < nr_args; i++) GDKfree(argtpe[i]);
+ GDKfree(argtpe);
+ }
+ if(argval){
+ for(i = 0; i < nr_args; i++) GDKfree(argval[i]);
+ GDKfree(argval);
+ }
}
-#define send_err(out, header, http_err, soap_err, err_reason) { \
- if (header) \
- stream_printf(out, "HTTP/1.1 %s\r\n" \
- "Content-type: text/xml; charset=\"utf-8\"\r\n\r\n",\
- http_err); \
- stream_printf(out, \
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
- "<env:Envelope xmlns:env=\"%s\">" \
- "<env:Body>" \
- "<env:Fault>" \
- "<env:Code><env:Value>%s</env:Value></env:Code>" \
- "<env:Reason>" \
- "<env:Text xml:lang=\"en\">%s</env:Text>" \
- "</env:Reason>" \
- "</env:Fault></env:Body></env:Envelope>", \
- SOAP_NS, soap_err, err_reason); \
+static INLINE void
+send_err(stream *out,
+ int header,
+ char *http_err,
+ char *soap_err,
+ char *err_reason)
+{
+ if (header)
+ stream_printf(out, "HTTP/1.1 %s\r\n"
+ "Content-type: text/xml; charset=\"utf-8\"\r\n\r\n",
+ http_err);
+ stream_printf(out,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<env:Envelope xmlns:env=\"%s\">"
+ "<env:Body>"
+ "<env:Fault>"
+ "<env:Code><env:Value>%s</env:Value></env:Code>"
+ "<env:Reason>"
+ "<env:Text xml:lang=\"en\">%s</env:Text>"
+ "</env:Reason>"
+ "</env:Fault></env:Body></env:Envelope>",
+ SOAP_NS, soap_err, err_reason);
}
/**
@@ -937,6 +949,8 @@
str *argval,
BAT *shredBAT)
{
+ char errbuf[GDKMAXERRLEN], *errbuf_bak = GDKerrbuf;
+
/* Possible values of serializeMode:
* 0: xml-noheader-xrpc
* This is the normal serialize mode used for XRPC calls
@@ -953,14 +967,22 @@
stream_printf(mc->c->fdout, "HTTP/1.1 200 OK\r\n"
"Content-type: text/xml; "
"charset=\"utf-8\"\r\n\r\n");
+
+ *errbuf = 0;
+ GDKsetbuf(errbuf);
char *err = xquery_method(mc, serializeMode, module, location,
method, argc, iterc, argcnt, argtpe,
argval, shredBAT);
if (err) {
+ if(err == ((char*)-1)) {
+ err = strstr(errbuf, "first error was:"); assert(err);
+ err = strstr(err, "!ERROR"); assert(err);
+ }
send_err(mc->c->fdout, 0, "", "env:Sender", err);
return GDK_FAIL;
}
stream_flush(mc->c->fdout);
+ GDKsetbuf(errbuf_bak);
return GDK_SUCCEED;
}
@@ -1095,6 +1117,7 @@
int ret = GDK_FAIL;
lng **argcnt = NULL;
+ lng time_xrpcServDeSeria = GDKusec();
/* we don't always have the second '/' */
if(uri[0] == '/') uri++;
if(uri[0] == '\0'){
@@ -1145,17 +1168,26 @@
str argtpe[2] = { "xs:string", "xs:document" };
str argval[2] = { uri , "0" };
- ret = execQuery(mc, 2, MXQ_ADMIN, location, method, 2, 1,
+ time_xrpcServDeSeria = GDKusec() - time_xrpcServDeSeria;
+
+ ret = execQuery(mc, 2|timing, MXQ_ADMIN, location, method, 2, 1,
argcnt, argtpe, argval, shredBAT);
BBPreclaim(shredBAT);
} else { /* GET/DELETE */
str argtpe[1] = { "xs:string" };
str argval[1] = { uri };
+ time_xrpcServDeSeria = GDKusec() - time_xrpcServDeSeria;
- ret = execQuery(mc, 2, MXQ_ADMIN, location, method, 1, 1,
+ ret = execQuery(mc, 2|timing, MXQ_ADMIN, location, method, 1, 1,
argcnt, argtpe, argval, NULL);
}
+ if (timing && ret != GDK_FAIL) {
+ fprintf(stdout,
+ "XRPC_Server_DeSerialisation: %lld microsec\n",
+ time_xrpcServDeSeria);
+ }
+
GDKfree(argcnt[0]);
GDKfree(argcnt);
return ret;
@@ -1179,7 +1211,7 @@
}
/* clean up */
- mc->engine = xquery_client_engine;
+ mc->engine = xquery_client_engine;
xquery_client_end(mc, NULL);
shttpd_finish(arg);
}
@@ -1223,14 +1255,15 @@
char *s;
if (rpcd_running) {
- stream_printf(GDKout, "\nRPC receiver already running\n");
+ stream_printf(GDKout,
+ "\nRPC receiver already running (on port %d)\n",
+ xrpc_port);
return GDK_SUCCEED;
}
xrpc_port = *port;
rpcd_running = 1;
-
/* find 'datadir' (often datadir = <prefix>/share), otherwise use
* "/usr/share", hence, httpd serves out <datadir>/MonetDB/xrpc */
if( !(s = GDKgetenv("datadir")) ){
@@ -1269,7 +1302,6 @@
return GDK_SUCCEED;
}
-
void xrpc_epilogue(void)
{
shttpd_fini(); /* Shut down the HTTP server. */
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins