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