When protocol closes DCB it calls dcb_close instead of dcb->func.close. dcb_close then calls dcb->func.close. This is now changed to all protocols and routers.

Rwsplit handles ERRACT_NEW_CONNECTION by clearing backend reference, removing callbacks and associating backend reference with new backend server. If it succeeds and the router session can continue, handleError returns true. Otherwise false. When ever false is returned it means that session must be closed.

Rwsplit now tolerates backend failures in a way that it searches new backends when monitor, backend, or client operation fails due to backend failure.
This commit is contained in:
VilhoRaatikka
2014-06-15 23:44:07 +03:00
parent 09d20d1059
commit 5bcae64538
16 changed files with 472 additions and 433 deletions

View File

@ -110,6 +110,7 @@ DCB *rval;
#if defined(SS_DEBUG)
rval->dcb_chk_top = CHK_NUM_DCB;
rval->dcb_chk_tail = CHK_NUM_DCB;
rval->dcb_errhandle_called = false;
#endif
rval->dcb_role = role;
#if 1
@ -149,7 +150,7 @@ DCB *rval;
/**
* Free a DCB that has not been associated with a decriptor.
* Free a DCB that has not been associated with a descriptor.
*
* @param dcb The DCB to free
*/
@ -957,7 +958,6 @@ int above_water;
if (dcb->writeq)
{
int len;
/*
* Loop over the buffer chain in the pending writeq
* Send as much of the data in that chain as possible and
@ -1042,9 +1042,7 @@ void
dcb_close(DCB *dcb)
{
int rc;
#if defined(ERRHANDLE)
bool isclient;
#endif
CHK_DCB(dcb);
/*<
@ -1062,21 +1060,13 @@ dcb_close(DCB *dcb)
dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE);
#if defined(ERRHANDLE)
isclient = dcb_isclient(dcb);
/*<
* Stop dcb's listening and modify state accordingly.
*/
rc = poll_remove_dcb(dcb);
if (isclient)
{
/*<
* Stop dcb's listening and modify state accordingly.
*/
rc = poll_remove_dcb(dcb);
ss_dassert(dcb->state == DCB_STATE_NOPOLLING ||
ss_dassert(dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE);
}
/**
* close protocol and router session
*/
@ -1085,26 +1075,6 @@ dcb_close(DCB *dcb)
dcb->func.close(dcb);
}
if (!isclient)
{
/*<
* Stop dcb's listening and modify state accordingly.
*/
rc = poll_remove_dcb(dcb);
ss_dassert(dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE);
}
#else
/*<
* Stop dcb's listening and modify state accordingly.
*/
rc = poll_remove_dcb(dcb);
ss_dassert(dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE);
#endif
dcb_call_callback(dcb, DCB_REASON_CLOSE);
if (rc == 0) {
@ -1654,7 +1624,7 @@ int rval = 0;
if (cb->reason == reason && cb->cb == callback
&& cb->userdata == userdata)
{
if (pcb == NULL)
if (pcb != NULL)
pcb->next = cb->next;
else
dcb->callbacks = cb->next;