wrote some code for connect timeout handling in mar.c

This commit is contained in:
hyung-hwan 2022-06-18 13:20:18 +00:00
parent fc160bf365
commit a700e7ac41
5 changed files with 83 additions and 32 deletions

View File

@ -210,7 +210,7 @@ int main (int argc, char* argv[])
hio_t* hio = HIO_NULL;
hio_svc_marc_t* marc;
hio_svc_marc_connect_t ci;
/* hio_svc_marc_tmout_t tmout;*/
hio_svc_marc_tmout_t tmout;
if (argc != 6)
{
@ -232,13 +232,12 @@ int main (int argc, char* argv[])
ci.password = argv[4];
ci.dbname = argv[5];
/* timeout not implemented yet in the mardiab device and services
HIO_INIT_NTIME (&tmout.c, 2, 0);
memset (&tmout, 0, HIO_SIZEOF(tmout));
HIO_INIT_NTIME (&tmout.c, 4, 0);
HIO_INIT_NTIME (&tmout.r, -1, 0);
HIO_INIT_NTIME (&tmout.w, -1, 0);
*/
marc = hio_svc_marc_start(hio, &ci, HIO_NULL, HIO_NULL);
marc = hio_svc_marc_start(hio, &ci, &tmout, HIO_NULL);
/*marc = hio_svc_marc_start(hio, &ci, HIO_NULL, HIO_NULL);*/
if (!marc)
{
printf ("Cannot start a mariadb client service\n");

View File

@ -76,6 +76,14 @@ typedef void (*hio_dev_mar_on_row_fetched_t) (
void* row_data
);
typedef struct hio_dev_mar_tmout_t hio_dev_mar_tmout_t;
struct hio_dev_mar_tmout_t
{
hio_ntime_t c;
hio_ntime_t r;
hio_ntime_t w;
};
struct hio_dev_mar_t
{
HIO_DEV_HEADER;
@ -84,6 +92,9 @@ struct hio_dev_mar_t
void* res;
hio_dev_mar_progress_t progress;
hio_dev_mar_tmout_t tmout;
hio_tmridx_t ctmridx;
unsigned int connected: 1;
unsigned int connected_deferred: 1;
unsigned int query_started_deferred: 1;
@ -109,15 +120,6 @@ enum hio_dev_mar_make_flag_t
};
typedef enum hio_dev_mar_make_flag_t hio_dev_mar_make_flag_t;
typedef struct hio_dev_mar_tmout_t hio_dev_mar_tmout_t;
struct hio_dev_mar_tmout_t
{
hio_ntime_t c;
hio_ntime_t r;
hio_ntime_t w;
};
typedef struct hio_dev_mar_make_t hio_dev_mar_make_t;
struct hio_dev_mar_make_t
{

View File

@ -26,7 +26,7 @@
#define _HIO_SHW_H_
/* system handle wrapper -
* turn a raw system handle/file descript to a device object
* turn a raw system handle/file descriptor to a device object
*/
#include <hio.h>

View File

@ -258,6 +258,7 @@ static void mar_on_disconnect (hio_dev_mar_t* dev)
sess->connected = 0;
/* give RCODE_ERROR to pending queries */
while (1)
{
sess_qry_t* sq;

View File

@ -43,6 +43,49 @@
/* ========================================================================= */
static void on_connect_timeout (hio_t* hio, const hio_ntime_t* now, hio_tmrjob_t* job)
{
hio_dev_mar_t* rdev = (hio_dev_mar_t*)job->ctx;
hio_dev_mar_halt (rdev);
}
static int sched_connect_timeout (hio_dev_t* dev)
{
hio_t* hio = dev->hio;
hio_dev_mar_t* rdev = (hio_dev_mar_t*)dev;
hio_tmrjob_t tmrjob;
if (rdev->tmout.c.sec >= 0)
{
HIO_MEMSET (&tmrjob, 0, HIO_SIZEOF(tmrjob));
tmrjob.ctx = rdev;
hio_gettime (hio, &tmrjob.when);
HIO_ADD_NTIME (&tmrjob.when, &tmrjob.when, &rdev->tmout.c);
tmrjob.handler = on_connect_timeout;
tmrjob.idxptr = &rdev->ctmridx;
rdev->ctmridx = hio_instmrjob(hio, &tmrjob);
if (rdev->ctmridx == HIO_TMRIDX_INVALID)
{
/* don't care about failure. timing out won't work */
/* TODO: fix this */
}
}
return 0;
}
static void desched_connect_timeout (hio_dev_t* dev)
{
hio_t* hio = dev->hio;
hio_dev_mar_t* rdev = (hio_dev_mar_t*)dev;
if (rdev->ctmridx != HIO_TMRIDX_INVALID)
{
hio_deltmrjob (hio, rdev->ctmridx);
HIO_ASSERT (hio, rdev->ctmridx == HIO_TMRIDX_INVALID);
}
}
static int dev_mar_make (hio_dev_t* dev, void* ctx)
{
hio_t* hio = dev->hio;
@ -72,24 +115,26 @@ static int dev_mar_make (hio_dev_t* dev, void* ctx)
mysql_options(rdev->hnd, MYSQL_OPT_RECONNECT, &x);
}
#if 0
/* TOOD: timeout not implemented...
* timeout can't be implemented using the mysql timeout options in the nonblocking mode.
* i must create a timeer jobs for these */
if (mi->flags & HIO_DEV_MAR_USE_TMOUT)
{
/* remember the timeout settings. use a negative second to indicate no timeout.
* the saved values will be used in scheduling a timer job for each relevant operation.
* Timing out can't be implemented with the standard MYSQL TIMEOUT options in
* the asynchronous mode. that is, this sample code doesn't work.
unsigned int tmout;
tmout = mi->tmout.c.sec; /* mysql supports the granularity of seconds only */
tmout = mi->tmout.c.sec; // mysql supports the granularity of seconds only
if (tmout >= 0) mysql_options(rdev->hnd, MYSQL_OPT_CONNECT_TIMEOUT, &tmout);
tmout = mi->tmout.r.sec;
if (tmout >= 0) mysql_options(rdev->hnd, MYSQL_OPT_READ_TIMEOUT, &tmout);
tmout = mi->tmout.w.sec;
if (tmout >= 0) mysql_options(rdev->hnd, MYSQL_OPT_WRITE_TIMEOUT, &tmout);
*/
rdev->tmout = mi->tmout;
if (!(mi->flags & HIO_DEV_MAR_USE_TMOUT))
{
rdev->tmout.c.sec = -1;
rdev->tmout.r.sec = -1;
rdev->tmout.w.sec = -1;
}
#endif
rdev->dev_cap = HIO_DEV_CAP_IN | HIO_DEV_CAP_OUT | HIO_DEV_CAP_VIRTUAL; /* mysql_init() doesn't create a socket. so no IO is possible at this point */
rdev->on_read = mi->on_read;
@ -100,15 +145,18 @@ static int dev_mar_make (hio_dev_t* dev, void* ctx)
rdev->on_row_fetched = mi->on_row_fetched;
rdev->progress = HIO_DEV_MAR_INITIAL;
rdev->ctmridx = HIO_TMRIDX_INVALID;
return 0;
}
static int dev_mar_kill (hio_dev_t* dev, int force)
{
/*hio_t* hio = dev->hio;*/
hio_t* hio = dev->hio;
hio_dev_mar_t* rdev = (hio_dev_mar_t*)dev;
desched_connect_timeout (dev);
/* if rdev->connected is 0 at this point,
* the underlying socket of this device is down */
if (HIO_LIKELY(rdev->on_disconnect)) rdev->on_disconnect (rdev);
@ -241,6 +289,7 @@ static int dev_mar_ioctl (hio_dev_t* dev, int cmd, void* arg)
if (status)
{
/* not connected */
sched_connect_timeout (dev);
HIO_DEV_MAR_SET_PROGRESS (rdev, HIO_DEV_MAR_CONNECTING);
watch_mysql (rdev, status);
}
@ -432,8 +481,8 @@ static int dev_evcb_mar_ready (hio_dev_t* dev, int events)
if (tmp)
{
/* established ok */
desched_connect_timeout (dev);
watch_mysql (rdev, status);
rdev->connected = 1; /* really connected */
HIO_DEV_MAR_SET_PROGRESS (rdev, HIO_DEV_MAR_CONNECTED);
if (rdev->on_connect) rdev->on_connect (rdev);
@ -443,7 +492,7 @@ static int dev_evcb_mar_ready (hio_dev_t* dev, int events)
/* connection attempt failed */
/* the mysql client library closes the underlying socket handle
* whenever the connection attempt fails. this prevent hio from
* whenever the connection attempt fails. this prevents hio from
* managing the the mysql connections properly. this also causes
* race condition if this library is used in multi-threaded programs. */
@ -463,8 +512,8 @@ static int dev_evcb_mar_ready (hio_dev_t* dev, int events)
watch_mysql (rdev, 0);
/* on_disconnect() will be called without on_connect().
* you may assume that the initial connectinon attempt failed.
* reconnectin doesn't apply in this context. */
* you may assume that the initial connection attempt failed.
* reconnection doesn't apply in this context. */
hio_dev_mar_halt (rdev);
}
}