From 9eda859724b1fb855eec360962a768b3d9981839 Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Fri, 13 Jun 2014 08:01:26 +0300 Subject: [PATCH] Added callback for rwsplit router which traverses through every rwsplit router session and for each rses, all backend references. Each bref is checked whether it is connected to non responsive server and if it is flagged to be waiting for response from the non-responsive backend. For matching ones, backend protocol's hangup function is called. --- server/core/dcb.c | 5 +- server/include/dcb.h | 3 +- .../routing/readwritesplit/readwritesplit.c | 61 +++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index be71d9677..2fcb1f2cc 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1579,7 +1579,10 @@ int gw_write( * @return Non-zero (true) if the callback was added */ int -dcb_add_callback(DCB *dcb, DCB_REASON reason, int (*callback)(struct dcb *, DCB_REASON, void *), void *userdata) +dcb_add_callback( + DCB *dcb, + DCB_REASON reason, + int (*callback)(struct dcb *, DCB_REASON, void *), void *userdata) { DCB_CALLBACK *cb, *ptr; int rval = 1; diff --git a/server/include/dcb.h b/server/include/dcb.h index 0672d5185..dfc97ccce 100644 --- a/server/include/dcb.h +++ b/server/include/dcb.h @@ -165,7 +165,8 @@ typedef enum { DCB_REASON_HIGH_WATER, /*< Cross high water mark */ DCB_REASON_LOW_WATER, /*< Cross low water mark */ DCB_REASON_ERROR, /*< An error was flagged on the connection */ - DCB_REASON_HUP /*< A hangup was detected */ + DCB_REASON_HUP, /*< A hangup was detected */ + DCB_REASON_NOT_RESPONDING /*< Server connection was lost */ } DCB_REASON; /** diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 951e2f343..564888ce5 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -224,6 +224,8 @@ static void refreshInstance( static void bref_clear_state(backend_ref_t* bref, bref_state_t state); static void bref_set_state(backend_ref_t* bref, bref_state_t state); +static int router_handle_not_responding(DCB* dcb, DCB_REASON reason, void* data); +static void hangup_server_connections (ROUTER_INSTANCE* inst); static SPINLOCK instlock; static ROUTER_INSTANCE* instances; @@ -1597,6 +1599,11 @@ static bool select_connect_backend_servers( if (backend_ref[i].bref_dcb != NULL) { slaves_connected += 1; + dcb_add_callback( + backend_ref[i].bref_dcb, + DCB_REASON_NOT_RESPONDING, + &router_handle_not_responding, + NULL); bref_clear_state(&backend_ref[i], BREF_NOT_USED); bref_set_state(&backend_ref[i], @@ -2736,4 +2743,58 @@ static backend_ref_t* get_bref_from_dcb( bref++; } return bref; +} + +static int router_handle_not_responding( + DCB* dcb, + DCB_REASON reason, + void* data) +{ + ROUTER_INSTANCE* inst; + + CHK_DCB(dcb); + CHK_SESSION(dcb->session); + inst = dcb->session->service->router_instance; + + switch (reason) { + case DCB_REASON_NOT_RESPONDING: + hangup_server_connections(inst); + break; + + default: + break; + } + + return 1; +} + +static void hangup_server_connections ( + ROUTER_INSTANCE* inst) +{ + ROUTER_CLIENT_SES* rses; + SERVER* fail_server; + + rses = inst->connections; + + while (rses != NULL) + { + backend_ref_t* bref; + + CHK_CLIENT_RSES(rses); + bref = rses->rses_backend_ref; + + while (bref != NULL) + { + CHK_BACKEND_REF(bref); + CHK_BACKEND(bref->bref_backend); + + if (bref->bref_backend->backend_server == fail_server && + BREF_IS_WAITING_RESPONSE(bref)) + { + bref->bref_dcb->func.hangup; + } + bref ++; + } + rses = rses->next; + } } \ No newline at end of file