MXS-936: add shutdown hooks

First part: add shutdown hooks for routers.

Binlog is the first one with a  destroyInstance() routine
This commit is contained in:
MassimilianoPinto
2016-11-08 11:12:37 +01:00
parent 689366b6b7
commit de18f25cb8
12 changed files with 92 additions and 10 deletions

View File

@ -24,6 +24,7 @@
* 16/07/2013 Massimiliano Pinto Added router commands values * 16/07/2013 Massimiliano Pinto Added router commands values
* 22/10/2013 Massimiliano Pinto Added router errorReply entry point * 22/10/2013 Massimiliano Pinto Added router errorReply entry point
* 27/10/2015 Martin Brampton Add RCAP_TYPE_NO_RSESSION * 27/10/2015 Martin Brampton Add RCAP_TYPE_NO_RSESSION
* 08/11/2016 Massimiliano Pinto Add destroyInstance() entry point
* *
*/ */
@ -82,6 +83,7 @@ typedef struct router_object
error_action_t action, error_action_t action,
bool* succp); bool* succp);
uint64_t (*getCapabilities)(void); uint64_t (*getCapabilities)(void);
void (*destroyInstance)(SERVICE *service);
} ROUTER_OBJECT; } ROUTER_OBJECT;
/** /**

View File

@ -34,6 +34,7 @@
* 03/03/15 Massimiliano Pinto Added config_enable_feedback_task() call in serviceStartAll * 03/03/15 Massimiliano Pinto Added config_enable_feedback_task() call in serviceStartAll
* 19/06/15 Martin Brampton More meaningful names for temp variables * 19/06/15 Martin Brampton More meaningful names for temp variables
* 31/05/16 Martin Brampton Implement connection throttling * 31/05/16 Martin Brampton Implement connection throttling
* 08/11/16 Massimiliano Pinto Added: service_shutdown() calls destroyInstance() hoosk for routers
* *
* @endverbatim * @endverbatim
*/ */
@ -1827,6 +1828,11 @@ void service_shutdown()
while (svc != NULL) while (svc != NULL)
{ {
svc->svc_do_shutdown = true; svc->svc_do_shutdown = true;
/* Call destroyInstance hook for routers */
if (svc->router->destroyInstance)
{
svc->router->destroyInstance(svc);
}
svc = svc->next; svc = svc->next;
} }
spinlock_release(&service_spin); spinlock_release(&service_spin);

View File

@ -105,7 +105,8 @@ static ROUTER_OBJECT MyObject =
diagnostics, diagnostics,
clientReply, clientReply,
errorReply, errorReply,
getCapabilities getCapabilities,
NULL
}; };
static SPINLOCK instlock; static SPINLOCK instlock;

View File

@ -50,6 +50,7 @@
* for connection error and authentication failure. * for connection error and authentication failure.
* 11/07/2016 Massimiliano Pinto Added SSL backend support * 11/07/2016 Massimiliano Pinto Added SSL backend support
* 22/07/2016 Massimiliano Pinto Added semi_sync replication support * 22/07/2016 Massimiliano Pinto Added semi_sync replication support
* 08/11/2016 Massimiliano Pinto Added destroyInstance()
* *
* @endverbatim * @endverbatim
*/ */
@ -108,6 +109,7 @@ static int blr_check_binlog(ROUTER_INSTANCE *router);
int blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug); int blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug);
void blr_master_close(ROUTER_INSTANCE *); void blr_master_close(ROUTER_INSTANCE *);
void blr_free_ssl_data(ROUTER_INSTANCE *inst); void blr_free_ssl_data(ROUTER_INSTANCE *inst);
static void destroyInstance(SERVICE *service);
/** The module object definition */ /** The module object definition */
static ROUTER_OBJECT MyObject = static ROUTER_OBJECT MyObject =
@ -120,7 +122,8 @@ static ROUTER_OBJECT MyObject =
diagnostics, diagnostics,
clientReply, clientReply,
errorReply, errorReply,
getCapabilities getCapabilities,
destroyInstance
}; };
static void stats_func(void *); static void stats_func(void *);
@ -2291,3 +2294,65 @@ blr_free_ssl_data(ROUTER_INSTANCE *inst)
inst->service->dbref->server->server_ssl = NULL; inst->service->dbref->server->server_ssl = NULL;
} }
} }
/**
* destroy binlog server instance
*
* @param service The service this router instance belongs to
*/
static void
destroyInstance(SERVICE *service)
{
ROUTER_INSTANCE *inst = (ROUTER_INSTANCE *) service->router_instance;
MXS_DEBUG("Destroying instance of router %s for service %s",
service->routerModule, service->name);
/* Check whether master connection is active */
if (inst->master)
{
if (inst->master->fd != -1 && inst->master->state == DCB_STATE_POLLING)
{
blr_master_close(inst);
}
}
spinlock_acquire(&inst->lock);
if (inst->master_state != BLRM_UNCONFIGURED)
{
inst->master_state = BLRM_SLAVE_STOPPED;
}
if (inst->client)
{
if (inst->client->state == DCB_STATE_POLLING)
{
dcb_close(inst->client);
inst->client = NULL;
}
}
/* Discard the queued residual data */
while (inst->residual)
{
inst->residual = gwbuf_consume(inst->residual, GWBUF_LENGTH(inst->residual));
}
inst->residual = NULL;
MXS_NOTICE("%s is being stopped by MaxScale shudown. Disconnecting from master %s:%d, "
"read up to log %s, pos %lu, transaction safe pos %lu",
service->name,
service->dbref->server->name,
service->dbref->server->port,
inst->binlog_name, inst->current_pos, inst->binlog_position);
if (inst->trx_safe && inst->pending_transaction)
{
MXS_WARNING("%s stopped by shutdown: detected mid-transaction in binlog file %s, "
"pos %lu, incomplete transaction starts at pos %lu",
service->name, inst->binlog_name, inst->current_pos, inst->binlog_position);
}
spinlock_release(&inst->lock);
}

View File

@ -71,7 +71,8 @@ static ROUTER_OBJECT MyObject =
diagnostics, diagnostics,
NULL, NULL,
NULL, NULL,
getCapabilities getCapabilities,
NULL
}; };
extern int execute_cmd(CLI_SESSION *cli); extern int execute_cmd(CLI_SESSION *cli);

View File

@ -70,7 +70,8 @@ static ROUTER_OBJECT MyObject =
diagnostics, diagnostics,
NULL, NULL,
NULL, NULL,
getCapabilities getCapabilities,
NULL
}; };
extern int execute_cmd(CLI_SESSION *cli); extern int execute_cmd(CLI_SESSION *cli);

View File

@ -96,7 +96,8 @@ static ROUTER_OBJECT MyObject =
diagnostics, diagnostics,
NULL, NULL,
handleError, handleError,
getCapabilities getCapabilities,
NULL
}; };
static SPINLOCK instlock; static SPINLOCK instlock;

View File

@ -125,7 +125,8 @@ static ROUTER_OBJECT MyObject =
diagnostics, diagnostics,
clientReply, clientReply,
handleError, handleError,
getCapabilities getCapabilities,
NULL
}; };
static bool rses_begin_locked_router_action(ROUTER_CLIENT_SES* rses); static bool rses_begin_locked_router_action(ROUTER_CLIENT_SES* rses);

View File

@ -101,7 +101,8 @@ static ROUTER_OBJECT MyObject =
diagnostics, diagnostics,
clientReply, clientReply,
handleError, handleError,
getCapabilities getCapabilities,
NULL
}; };
/* /*

View File

@ -113,7 +113,8 @@ static ROUTER_OBJECT MyObject =
diagnostic, diagnostic,
clientReply, clientReply,
handleError, handleError,
getCapabilities getCapabilities,
NULL
}; };
static bool rses_begin_locked_router_action(ROUTER_CLIENT_SES* rses); static bool rses_begin_locked_router_action(ROUTER_CLIENT_SES* rses);

View File

@ -50,7 +50,8 @@ static ROUTER_OBJECT MyObject =
diagnostic, diagnostic,
clientReply, clientReply,
handleError, handleError,
getCapabilities getCapabilities,
NULL
}; };
typedef struct typedef struct

View File

@ -64,7 +64,8 @@ static ROUTER_OBJECT MyObject =
diagnostic, diagnostic,
NULL, NULL,
NULL, NULL,
getCapabilities getCapabilities,
NULL
}; };