Module: sip-router
Branch: master
Commit: b46c6f66e1aa64bc038d7495915c0fd646fcf8fe
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b46c6f6…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Tue Apr 10 00:00:05 2012 +0200
db_cluster: if a db query fails, mark connection inactive
- default inactive time is 300sec
- value can be chanded via inactive_interval parameter
---
modules_k/db_cluster/db_cluster_mod.c | 3 ++
modules_k/db_cluster/dbcl_api.c | 44 ++++++++++++++++++++++++---------
modules_k/db_cluster/dbcl_data.c | 28 +++++++++++++++++++++
modules_k/db_cluster/dbcl_data.h | 7 ++++-
4 files changed, 69 insertions(+), 13 deletions(-)
diff --git a/modules_k/db_cluster/db_cluster_mod.c
b/modules_k/db_cluster/db_cluster_mod.c
index 12f642c..c0b78cb 100644
--- a/modules_k/db_cluster/db_cluster_mod.c
+++ b/modules_k/db_cluster/db_cluster_mod.c
@@ -36,6 +36,8 @@ int db_cluster_bind_api(db_func_t *dbb);
int dbcl_con_param(modparam_t type, void *val);
int dbcl_cls_param(modparam_t type, void *val);
+int dbcl_inactive_interval = 300;
+
/*! \brief
* DB Cluster module interface
*/
@@ -50,6 +52,7 @@ static cmd_export_t cmds[] = {
static param_export_t params[] = {
{"connection", STR_PARAM|USE_FUNC_PARAM, (void*)dbcl_con_param},
{"cluster", STR_PARAM|USE_FUNC_PARAM, (void*)dbcl_cls_param},
+ {"inactive_interval", INT_PARAM, &dbcl_inactive_interval},
{0, 0, 0}
};
diff --git a/modules_k/db_cluster/dbcl_api.c b/modules_k/db_cluster/dbcl_api.c
index 430ea98..9f79f35 100644
--- a/modules_k/db_cluster/dbcl_api.c
+++ b/modules_k/db_cluster/dbcl_api.c
@@ -47,7 +47,7 @@
db1_con_t *dbh=NULL;\
dbcl_cls_t *cls=NULL;\
cls = (dbcl_cls_t*)_h->tail;\
- ret = 0;\
+ ret = -1;\
for(i=DBCL_PRIO_SIZE-1; i>0; i--)\
{\
switch(cls->rlist[i].mode) {\
@@ -55,8 +55,7 @@
case 'S':\
for(j=0; j<cls->rlist[i].clen; j++)\
{\
- if(cls->rlist[i].clist[j] != NULL &&
cls->rlist[i].clist[j]->flags!=0\
- && cls->rlist[i].clist[j]->dbh != NULL)\
+ if(dbcl_valid_con(cls->rlist[i].clist[j])==0)\
{\
LM_DBG("serial operation - cluster [%.*s] (%d/%d)\n",\
cls->name.len, cls->name.s, i, j);\
@@ -65,6 +64,11 @@
if (ret==0) {\
cls->usedcon = cls->rlist[i].clist[j];\
return 0;\
+ } else {\
+ LM_DBG("serial operation - failre on cluster"\
+ " [%.*s] (%d/%d)\n",\
+ cls->name.len, cls->name.s, i, j);\
+ dbcl_inactive_con(cls->rlist[i].clist[j]);\
}\
}\
}\
@@ -74,8 +78,7 @@
for(k=0; k<cls->rlist[i].clen; k++)\
{\
j = (process_no + k + cls->rlist[i].crt) % cls->rlist[i].clen;\
- if(cls->rlist[i].clist[j] != NULL &&
cls->rlist[i].clist[j]->flags!=0\
- && cls->rlist[i].clist[j]->dbh != NULL)\
+ if(dbcl_valid_con(cls->rlist[i].clist[j])==0)\
{\
LM_DBG("round robin operation - cluster [%.*s] (%d/%d)\n",\
cls->name.len, cls->name.s, i, j);\
@@ -86,6 +89,11 @@
cls->usedcon = cls->rlist[i].clist[j];\
cls->rlist[i].crt = (j+1) % cls->rlist[i].clen;\
return 0;\
+ } else {\
+ LM_DBG("round robin operation - failre on cluster"\
+ " [%.*s] (%d/%d)\n",\
+ cls->name.len, cls->name.s, i, j);\
+ dbcl_inactive_con(cls->rlist[i].clist[j]);\
}\
}\
}\
@@ -110,7 +118,7 @@
db1_con_t *dbh=NULL;\
dbcl_cls_t *cls=NULL;\
cls = (dbcl_cls_t*)_h->tail;\
- ret = 0;\
+ ret = -1;\
rok = 0;\
rc = 0;\
for(i=DBCL_PRIO_SIZE-1; i>0; i--)\
@@ -120,8 +128,7 @@
case 'S':\
for(j=0; j<cls->wlist[i].clen; j++)\
{\
- if(cls->wlist[i].clist[j] != NULL &&
cls->wlist[i].clist[j]->flags!=0\
- && cls->wlist[i].clist[j]->dbh != NULL)\
+ if(dbcl_valid_con(cls->wlist[i].clist[j])==0)\
{\
LM_DBG("serial operation - cluster [%.*s] (%d/%d)\n",\
cls->name.len, cls->name.s, i, j);\
@@ -130,6 +137,11 @@
if (ret==0) {\
cls->usedcon = cls->wlist[i].clist[j];\
return 0;\
+ } else {\
+ LM_DBG("serial operation - failure on cluster"\
+ " [%.*s] (%d/%d)\n",\
+ cls->name.len, cls->name.s, i, j);\
+ dbcl_inactive_con(cls->wlist[i].clist[j]);\
}\
}\
}\
@@ -139,8 +151,7 @@
for(k=0; k<cls->wlist[i].clen; k++)\
{\
j = (process_no + k + cls->wlist[i].crt) % cls->wlist[i].clen;\
- if(cls->wlist[i].clist[j] != NULL &&
cls->wlist[i].clist[j]->flags!=0\
- && cls->wlist[i].clist[j]->dbh != NULL)\
+ if(dbcl_valid_con(cls->wlist[i].clist[j])==0)\
{\
LM_DBG("round robin operation - cluster [%.*s] (%d/%d)\n",\
cls->name.len, cls->name.s, i, j);\
@@ -151,6 +162,11 @@
cls->usedcon = cls->wlist[i].clist[j];\
cls->wlist[i].crt = (j+1) % cls->wlist[i].clen;\
return 0;\
+ } else {\
+ LM_DBG("round robin operation - failure on cluster"\
+ " [%.*s] (%d/%d)\n",\
+ cls->name.len, cls->name.s, i, j);\
+ dbcl_inactive_con(cls->wlist[i].clist[j]);\
}\
}\
}\
@@ -159,8 +175,7 @@
case 'P':\
for(j=0; j<cls->wlist[i].clen; j++)\
{\
- if(cls->wlist[i].clist[j] != NULL &&
cls->wlist[i].clist[j]->flags!=0\
- && cls->wlist[i].clist[j]->dbh != NULL)\
+ if(dbcl_valid_con(cls->wlist[i].clist[j])==0)\
{\
LM_DBG("parallel operation - cluster [%.*s] (%d/%d)\n",\
cls->name.len, cls->name.s, i, j);\
@@ -169,6 +184,11 @@
if(rc==0) {\
cls->usedcon = cls->wlist[i].clist[j];\
rok = 1;\
+ } else {\
+ LM_DBG("parallel operation - failure on cluster"\
+ " [%.*s] (%d/%d)\n",\
+ cls->name.len, cls->name.s, i, j);\
+ dbcl_inactive_con(cls->wlist[i].clist[j]);\
}\
ret |= rc;\
}\
diff --git a/modules_k/db_cluster/dbcl_data.c b/modules_k/db_cluster/dbcl_data.c
index bb5d5fb..9533421 100644
--- a/modules_k/db_cluster/dbcl_data.c
+++ b/modules_k/db_cluster/dbcl_data.c
@@ -32,6 +32,7 @@
#include "../../dprint.h"
#include "../../hashes.h"
#include "../../trim.h"
+#include "../../timer.h"
#include "../../mem/mem.h"
#include "../../mem/shm_mem.h"
@@ -123,6 +124,33 @@ int dbcl_init_con(str *name, str *url)
return 0;
}
+int dbcl_valid_con(dbcl_con_t *sc)
+{
+ if(sc==NULL || sc->flags!=0 || sc->dbh!=NULL)
+ return -1;
+ if(sc->sinfo==NULL)
+ return 0;
+ if(sc->sinfo->state & DBCL_CON_INACTIVE)
+ {
+ if(sc->sinfo->aticks>0 && sc->sinfo->aticks<get_ticks())
+ return -1;
+ sc->sinfo->aticks = 0;
+ sc->sinfo->state &= ~DBCL_CON_INACTIVE;
+ }
+ return 0;
+}
+
+extern int dbcl_inactive_interval;
+
+int dbcl_inactive_con(dbcl_con_t *sc)
+{
+ if(sc==NULL || sc->sinfo==NULL)
+ return -1;
+ sc->sinfo->aticks = get_ticks() + dbcl_inactive_interval;
+ sc->sinfo->state |= DBCL_CON_INACTIVE;
+ return 0;
+}
+
int dbcl_parse_con_param(char *val)
{
str name;
diff --git a/modules_k/db_cluster/dbcl_data.h b/modules_k/db_cluster/dbcl_data.h
index cc7a64b..ffb2c9f 100644
--- a/modules_k/db_cluster/dbcl_data.h
+++ b/modules_k/db_cluster/dbcl_data.h
@@ -40,10 +40,12 @@
#define DBCL_PRIO_SIZE 10
#define DBCL_CLIST_SIZE 5
+#define DBCL_CON_INACTIVE 1
+
typedef struct dbcl_shared
{
int state;
- int count;
+ unsigned int aticks;
} dbcl_shared_t;
typedef struct dbcl_con
@@ -84,6 +86,9 @@ int dbcl_init_connections(dbcl_cls_t *cls);
int dbcl_close_connections(dbcl_cls_t *cls);
dbcl_cls_t *dbcl_get_cluster(str *name);
+int dbcl_valid_con(dbcl_con_t *sc);
+int dbcl_inactive_con(dbcl_con_t *sc);
+
int dbcl_parse_con_param(char *val);
int dbcl_parse_cls_param(char *val);
#endif /* KM_DBASE_H */