Skip to content

Commit

Permalink
Added async timeout support in db_mysql & integrated that into avpops…
Browse files Browse the repository at this point in the history
… avp_db_query
  • Loading branch information
vladpaiu committed Jul 19, 2023
1 parent cfcd9a6 commit 2ff4955
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 0 deletions.
14 changes: 14 additions & 0 deletions db/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,18 @@ typedef int (*db_async_resume_f) (db_con_t *_h, int fd, db_res_t **_r,
*/
typedef int (*db_async_free_result_f) (db_con_t *_h, db_res_t *_r, void *_priv);

/*
* \brief Performs the necessary cleanup of asynchronous query results and
* their associated internal structures after there was a timeout
*
* \param _h structure representing the database handle
* \param _priv data that shall be populated by the engine
* !!! the same data pointer passed to the "query" and "resume" calls
* \return:
* -> 0 on success, negative on failure
*/
typedef void (*db_async_timeout_f) (db_con_t *_h, int fd, void *_priv);

/**
* \brief Database module callbacks
*
Expand All @@ -359,6 +371,8 @@ typedef struct db_func {
db_async_raw_query_f async_raw_query; /* Starts an asynchronous raw query */
db_async_resume_f async_resume; /* Called on progress or completed query */
db_async_free_result_f async_free_result; /* Clean up after an async query */

db_async_timeout_f async_timeout; /* Cleans up after async timed out query */
} db_func_t;


Expand Down
13 changes: 13 additions & 0 deletions modules/avpops/avpops_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,9 @@ int ops_async_dbquery(struct sip_msg* msg, async_ctx *ctx,

ctx->resume_param = param;
ctx->resume_f = resume_async_dbquery;
/* if supported in the backend */
if (url->dbf.async_timeout != NULL)
ctx->timeout_f = timeout_async_dbquery;

param->output_avps = dest;
param->hdl = url->hdl;
Expand All @@ -854,6 +857,16 @@ int ops_async_dbquery(struct sip_msg* msg, async_ctx *ctx,
return 1;
}

int timeout_async_dbquery(int fd, struct sip_msg *msg, void *_param)
{
query_async_param *param = (query_async_param *)_param;

param->dbf->async_timeout(param->hdl, fd, param->db_param);

/* this in an error case */
return -1;
}

int resume_async_dbquery(int fd, struct sip_msg *msg, void *_param)
{
db_res_t *res = NULL;
Expand Down
1 change: 1 addition & 0 deletions modules/avpops/avpops_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ int ops_async_dbquery(struct sip_msg* msg, async_ctx *ctx,
str *query, struct db_url *url, pvname_list_t *dest);

int resume_async_dbquery(int fd, struct sip_msg *msg, void *_param);
int timeout_async_dbquery(int fd, struct sip_msg *msg, void *_param);

int ops_delete_avp(struct sip_msg* msg,
struct fis_param *ap);
Expand Down
1 change: 1 addition & 0 deletions modules/db_mysql/db_mysql.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ int db_mysql_bind_api(const str* mod, db_func_t *dbb)
dbb->async_raw_query = db_mysql_async_raw_query;
dbb->async_resume = db_mysql_async_resume;
dbb->async_free_result = db_mysql_async_free_result;
dbb->async_timeout = db_mysql_async_timeout;

dbb->cap |= DB_CAP_MULTIPLE_INSERT;
return 0;
Expand Down
22 changes: 22 additions & 0 deletions modules/db_mysql/dbase.c
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,28 @@ int db_mysql_async_raw_query(db_con_t *_h, const str *_s, void **_priv)
return -2;
}

void db_mysql_async_timeout(db_con_t *_h, int fd, void *_priv)
{
struct pool_con *con = (struct pool_con *)_priv;

#ifdef EXTRA_DEBUG
if (!db_match_async_con(fd, _h)) {
LM_BUG("no conn match for fd %d", fd);
abort();
}
#endif

db_switch_to_async(_h, con);
mysql_free_result(CON_RESULT(_h));
CON_RESULT(_h) = NULL;

/* we timed out, might as well disconnect */
switch_state_to_disconnected(_h);

db_switch_to_sync(_h);
db_store_async_con(_h, con);
}

int db_mysql_async_resume(db_con_t *_h, int fd, db_res_t **_r, void *_priv)
{
struct pool_con *con = (struct pool_con *)_priv;
Expand Down
3 changes: 3 additions & 0 deletions modules/db_mysql/dbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ int db_mysql_async_raw_query(db_con_t *_h, const str *_s, void** _data);
*/
int db_mysql_async_resume(db_con_t *_h, int fd, db_res_t **_r, void* _data);

/* cleans up after a timeout on an async DB query */
void db_mysql_async_timeout(db_con_t *_h, int fd, void *_priv);

/*
* Cleans up asynchronous query results along with other associated structures
*
Expand Down

0 comments on commit 2ff4955

Please sign in to comment.