Changeset: 007271050deb for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=007271050deb
Modified Files:
        monetdb5/mal/mal_client.c
        monetdb5/mal/mal_client.h
        monetdb5/mal/mal_errors.h
        monetdb5/mal/mal_interpreter.c
        monetdb5/modules/mal/clients.c
        monetdb5/modules/mal/clients.mal
        monetdb5/modules/mal/mat.c
        sql/backends/monet5/sql.mx
        sql/scripts/22_clients.sql
Branch: default
Log Message:

Query and session timeouts
Both query and session timeouts can be set by specifying the max seconds 
allowed.
The session timeout check runs at the beginning of a query.
The query timeout is checked between all MAL instructions.

A timeout raises a MAL exception, which translates into a SQL transaction abort.


diffs (213 lines):

diff --git a/monetdb5/mal/mal_client.c b/monetdb5/mal/mal_client.c
--- a/monetdb5/mal/mal_client.c
+++ b/monetdb5/mal/mal_client.c
@@ -227,6 +227,7 @@ MCinitClientRecord(Client c, oid user, b
 
        c->father = NULL;
        c->login = c->lastcmd = time(0);
+       c->session = GDKusec();
        c->qtimeout = 0;
        c->stimeout = 0;
        c->stage = 0;
diff --git a/monetdb5/mal/mal_client.h b/monetdb5/mal/mal_client.h
--- a/monetdb5/mal/mal_client.h
+++ b/monetdb5/mal/mal_client.h
@@ -94,8 +94,9 @@ typedef struct CLIENT {
 
        time_t      login;  
        time_t      lastcmd;    /* set when input is received */
-       lng         qtimeout;   /* query abort after x milliseconds */
-       lng             stimeout;       /* session abort after x milliseconds */
+       lng             session;        /* usec since start of server */
+       lng         qtimeout;   /* query abort after x usec*/
+       lng             stimeout;       /* session abort after x usec */
        /*
         * Communication channels for the interconnect are stored here.
         * It is perfectly legal to have a client without input stream.
diff --git a/monetdb5/mal/mal_errors.h b/monetdb5/mal/mal_errors.h
--- a/monetdb5/mal/mal_errors.h
+++ b/monetdb5/mal/mal_errors.h
@@ -100,6 +100,7 @@
 #define RUNTIME_OBJECT_UNDEFINED "Object not found"
 #define RUNTIME_UNKNOWN_INSTRUCTION "Instruction type not supported"
 #define RUNTIME_QRY_TIMEOUT "Query aborted due to timeout"
+#define RUNTIME_SESSION_TIMEOUT "Query aborted due to session timeout"
 #define OPERATION_FAILED "operation failed"
 
 #define BOX_CLOSED "Box is not open"
diff --git a/monetdb5/mal/mal_interpreter.c b/monetdb5/mal/mal_interpreter.c
--- a/monetdb5/mal/mal_interpreter.c
+++ b/monetdb5/mal/mal_interpreter.c
@@ -381,7 +381,7 @@ str runMAL(Client cntxt, MalBlkPtr mb, M
                garbageCollector(cntxt, mb, stk, env != stk);
        if (stk && stk != env)
                GDKfree(stk);
-       if (cntxt->qtimeout && GDKms() > cntxt->qtimeout)
+       if (cntxt->qtimeout && GDKusec()- mb->starttime > cntxt->qtimeout)
                throw(MAL, "mal.interpreter", RUNTIME_QRY_TIMEOUT);
        return ret;
 }
@@ -473,7 +473,7 @@ callMAL(Client cntxt, MalBlkPtr mb, MalS
                throw(MAL, "mal.interpreter", RUNTIME_UNKNOWN_INSTRUCTION);
        }
        MT_sema_up(&mal_parallelism,"callMAL");
-       if (cntxt->qtimeout && GDKms() > cntxt->qtimeout)
+       if (cntxt->qtimeout && GDKusec()- mb->starttime > cntxt->qtimeout)
                throw(MAL, "mal.interpreter", RUNTIME_QRY_TIMEOUT);
        return ret;
 }
@@ -519,6 +519,8 @@ str runMALsequence(Client cntxt, MalBlkP
                runtimeProfileInit(cntxt, mb, stk);
                runtimeProfileBegin(cntxt, mb, stk, 0, &runtimeProfileFunction, 
1);
                mb->starttime = GDKusec();
+               if (cntxt->stimeout && cntxt->session && GDKusec()- 
cntxt->session > cntxt->stimeout)
+                       throw(MAL, "mal.interpreter", RUNTIME_SESSION_TIMEOUT);
        } 
        stkpc = startpc;
        exceptionVar = -1;
@@ -711,7 +713,7 @@ str runMALsequence(Client cntxt, MalBlkP
                                runtimeProfileFinish(cntxt, mb);
                                if (pcicaller && garbageControl(getInstrPtr(mb, 
0)))
                                        garbageCollector(cntxt, mb, stk, TRUE);
-                               if (cntxt->qtimeout && GDKms() > 
cntxt->qtimeout){
+                               if (cntxt->qtimeout && GDKusec()- mb->starttime 
> cntxt->qtimeout){
                                        ret= createException(MAL, 
"mal.interpreter", RUNTIME_QRY_TIMEOUT);
                                        break;
                                }
@@ -726,7 +728,7 @@ str runMALsequence(Client cntxt, MalBlkP
                                w= instruction2str(mb, 0, pci, FALSE);
                                ret = createScriptException(mb, stkpc, MAL, 
NULL, "unkown operation:%s",w);
                                GDKfree(w);
-                               if (cntxt->qtimeout && GDKms() > 
cntxt->qtimeout){
+                               if (cntxt->qtimeout && GDKusec()- mb->starttime 
> cntxt->qtimeout){
                                        ret= createException(MAL, 
"mal.interpreter", RUNTIME_QRY_TIMEOUT);
                                        break;
                                }
@@ -862,7 +864,7 @@ str runMALsequence(Client cntxt, MalBlkP
                                if (exceptionVar == -1) {
                                        runtimeProfileExit(cntxt, mb, stk, pci, 
&runtimeProfile);
                                        runtimeProfileFinish(cntxt, mb);
-                                       if (cntxt->qtimeout && GDKms() > 
cntxt->qtimeout)
+                                       if (cntxt->qtimeout && GDKusec()- 
mb->starttime > cntxt->qtimeout)
                                                ret= createException(MAL, 
"mal.interpreter", RUNTIME_QRY_TIMEOUT);
                                        stkpc = mb->stop;
                                        continue;
@@ -909,7 +911,7 @@ str runMALsequence(Client cntxt, MalBlkP
                                        }
                                }
                                if (stkpc == mb->stop) {
-                                       if (cntxt->qtimeout && GDKms() > 
cntxt->qtimeout){
+                                       if (cntxt->qtimeout && GDKusec()- 
mb->starttime > cntxt->qtimeout){
                                                ret= createException(MAL, 
"mal.interpreter", RUNTIME_QRY_TIMEOUT);
                                                stkpc = mb->stop;
                                        }
@@ -1132,7 +1134,7 @@ str runMALsequence(Client cntxt, MalBlkP
                default:
                        stkpc++;
                }
-               if (cntxt->qtimeout && GDKms() > cntxt->qtimeout){
+               if (cntxt->qtimeout && GDKusec()- mb->starttime > 
cntxt->qtimeout){
                        ret= createException(MAL, "mal.interpreter", 
RUNTIME_QRY_TIMEOUT);
                        stkpc= mb->stop;
                }
diff --git a/monetdb5/modules/mal/clients.c b/monetdb5/modules/mal/clients.c
--- a/monetdb5/modules/mal/clients.c
+++ b/monetdb5/modules/mal/clients.c
@@ -359,14 +359,18 @@ CLTsuspend(Client cntxt, MalBlkPtr mb, M
     return MCsuspendClient(*id);
 }
 
+//set time out based on seconds
 str
 CLTsetTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       lng qto=  *(lng *) getArgReference(stk,pci,1);
-       lng sto=  *(lng *) getArgReference(stk,pci,2);
+       lng qto,sto;
        (void) mb;
-       cntxt->qtimeout = qto;
-       cntxt->stimeout = sto;
+       qto=  *(lng *) getArgReference(stk,pci,1);
+       cntxt->qtimeout = qto * 1000 * 1000;
+       if ( pci->argc == 3){
+               sto=  *(lng *) getArgReference(stk,pci,2);
+               cntxt->stimeout = sto * 1000 * 1000;
+       }
     return MAL_SUCCEED;
 }
 str
diff --git a/monetdb5/modules/mal/clients.mal b/monetdb5/modules/mal/clients.mal
--- a/monetdb5/modules/mal/clients.mal
+++ b/monetdb5/modules/mal/clients.mal
@@ -71,9 +71,13 @@ command wakeup(id:int):void
 address CLTwakeup
 comment "Wakeup a client process";
 
+pattern settimeout(n:lng):void
+address CLTsettimeout
+comment "Abort a query after  n seconds.";
+
 pattern setTimeout(q:lng,s:lng):void
 address CLTsetTimeout
-comment "Abort a query after q milliseconds (q=0 means run undisturbed).
+comment "Abort a query after q seconds (q=0 means run undisturbed).
 The session timeout aborts the connection after spending too
 many seconds on query processing.";
 
diff --git a/monetdb5/modules/mal/mat.c b/monetdb5/modules/mal/mat.c
--- a/monetdb5/modules/mal/mat.c
+++ b/monetdb5/modules/mal/mat.c
@@ -461,7 +461,7 @@ MATmergepack(Client cntxt, MalBlkPtr mb,
        bn = BATnew(TYPE_void, TYPE_oid, cap);
        if (bn == NULL)
                throw(MAL, "mat.pack", MAL_MALLOC_FAIL);
-
+       BATsettrivprop(bn);
        for (i = 1; i < p->argc; i++) {
                b = BATdescriptor(stk->stk[getArg(p,i)].val.ival);
                if( b ){
@@ -473,7 +473,6 @@ MATmergepack(Client cntxt, MalBlkPtr mb,
        }
        assert(!bn->H->nil || !bn->H->nonil);
        assert(!bn->T->nil || !bn->T->nonil);
-       BATsettrivprop(bn);
        BBPkeepref(*ret = bn->batCacheid);
        return MAL_SUCCEED;
 }
diff --git a/sql/backends/monet5/sql.mx b/sql/backends/monet5/sql.mx
--- a/sql/backends/monet5/sql.mx
+++ b/sql/backends/monet5/sql.mx
@@ -477,7 +477,15 @@ comment "return table of users with sql 
 
 pattern password(user:str) :str
 address db_password_wrap
-comment "return password hash of user";
+comment "Return password hash of user";
+
+pattern settimeout(s:lng):void
+address CLTsetTimeout
+comment "Abort query after s seconds";
+
+pattern settimeout(s:lng,t:lng):void
+address CLTsetTimeout
+comment "Abort query after s and session after t seconds";
 
 pattern dump_cache()(query:bat[:oid,:str],count:bat[:oid,:int])
 address dump_cache
diff --git a/sql/scripts/22_clients.sql b/sql/scripts/22_clients.sql
--- a/sql/scripts/22_clients.sql
+++ b/sql/scripts/22_clients.sql
@@ -14,6 +14,12 @@
 -- Copyright August 2008-2013 MonetDB B.V.
 -- All Rights Reserved.
 
-create function password_hash (username string) 
+create function sys.password_hash (username string) 
        returns string 
        external name sql.password;
+
+-- control the query time out 
+create procedure sys.settimeout("query" bigint)
+       external name sql.settimeout;
+create procedure sys.settimeout("query" bigint, "session" bigint)
+       external name sql.settimeout;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to