diff --git a/include/maxscale/router.h b/include/maxscale/router.h index 90e8083d0..85625ae39 100644 --- a/include/maxscale/router.h +++ b/include/maxscale/router.h @@ -24,6 +24,7 @@ * 16/07/2013 Massimiliano Pinto Added router commands values * 22/10/2013 Massimiliano Pinto Added router errorReply entry point * 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, bool* succp); uint64_t (*getCapabilities)(void); + void (*destroyInstance)(SERVICE *service); } ROUTER_OBJECT; /** diff --git a/server/core/service.c b/server/core/service.c index f8f2a77a7..a8050ff91 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -34,6 +34,7 @@ * 03/03/15 Massimiliano Pinto Added config_enable_feedback_task() call in serviceStartAll * 19/06/15 Martin Brampton More meaningful names for temp variables * 31/05/16 Martin Brampton Implement connection throttling + * 08/11/16 Massimiliano Pinto Added: service_shutdown() calls destroyInstance() hoosk for routers * * @endverbatim */ @@ -1827,6 +1828,11 @@ void service_shutdown() while (svc != NULL) { svc->svc_do_shutdown = true; + /* Call destroyInstance hook for routers */ + if (svc->router->destroyInstance) + { + svc->router->destroyInstance(svc); + } svc = svc->next; } spinlock_release(&service_spin); diff --git a/server/modules/routing/avro/avro.c b/server/modules/routing/avro/avro.c index 54f256d3c..85c63ebfb 100644 --- a/server/modules/routing/avro/avro.c +++ b/server/modules/routing/avro/avro.c @@ -105,7 +105,8 @@ static ROUTER_OBJECT MyObject = diagnostics, clientReply, errorReply, - getCapabilities + getCapabilities, + NULL }; static SPINLOCK instlock; diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index eec12b98f..2cb4b0a71 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -50,6 +50,7 @@ * for connection error and authentication failure. * 11/07/2016 Massimiliano Pinto Added SSL backend support * 22/07/2016 Massimiliano Pinto Added semi_sync replication support + * 08/11/2016 Massimiliano Pinto Added destroyInstance() * * @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); void blr_master_close(ROUTER_INSTANCE *); void blr_free_ssl_data(ROUTER_INSTANCE *inst); +static void destroyInstance(SERVICE *service); /** The module object definition */ static ROUTER_OBJECT MyObject = @@ -120,7 +122,8 @@ static ROUTER_OBJECT MyObject = diagnostics, clientReply, errorReply, - getCapabilities + getCapabilities, + destroyInstance }; static void stats_func(void *); @@ -2291,3 +2294,65 @@ blr_free_ssl_data(ROUTER_INSTANCE *inst) 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); +} diff --git a/server/modules/routing/cli/cli.c b/server/modules/routing/cli/cli.c index ee263009e..478a2dcdf 100644 --- a/server/modules/routing/cli/cli.c +++ b/server/modules/routing/cli/cli.c @@ -71,7 +71,8 @@ static ROUTER_OBJECT MyObject = diagnostics, NULL, NULL, - getCapabilities + getCapabilities, + NULL }; extern int execute_cmd(CLI_SESSION *cli); diff --git a/server/modules/routing/debugcli/debugcli.c b/server/modules/routing/debugcli/debugcli.c index 962fbe1b4..1f86c82fc 100644 --- a/server/modules/routing/debugcli/debugcli.c +++ b/server/modules/routing/debugcli/debugcli.c @@ -70,7 +70,8 @@ static ROUTER_OBJECT MyObject = diagnostics, NULL, NULL, - getCapabilities + getCapabilities, + NULL }; extern int execute_cmd(CLI_SESSION *cli); diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index 135de44f0..05eaa8d4d 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -96,7 +96,8 @@ static ROUTER_OBJECT MyObject = diagnostics, NULL, handleError, - getCapabilities + getCapabilities, + NULL }; static SPINLOCK instlock; diff --git a/server/modules/routing/readconnroute/readconnroute.c b/server/modules/routing/readconnroute/readconnroute.c index a77dad041..e6d2ecfc3 100644 --- a/server/modules/routing/readconnroute/readconnroute.c +++ b/server/modules/routing/readconnroute/readconnroute.c @@ -125,7 +125,8 @@ static ROUTER_OBJECT MyObject = diagnostics, clientReply, handleError, - getCapabilities + getCapabilities, + NULL }; static bool rses_begin_locked_router_action(ROUTER_CLIENT_SES* rses); diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 357ab9610..a7f6532e8 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -101,7 +101,8 @@ static ROUTER_OBJECT MyObject = diagnostics, clientReply, handleError, - getCapabilities + getCapabilities, + NULL }; /* diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index ce6bcecec..1a7f12bda 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -113,7 +113,8 @@ static ROUTER_OBJECT MyObject = diagnostic, clientReply, handleError, - getCapabilities + getCapabilities, + NULL }; static bool rses_begin_locked_router_action(ROUTER_CLIENT_SES* rses); diff --git a/server/modules/routing/testroute/testroute.c b/server/modules/routing/testroute/testroute.c index 502e7cfab..7449822ce 100644 --- a/server/modules/routing/testroute/testroute.c +++ b/server/modules/routing/testroute/testroute.c @@ -50,7 +50,8 @@ static ROUTER_OBJECT MyObject = diagnostic, clientReply, handleError, - getCapabilities + getCapabilities, + NULL }; typedef struct diff --git a/server/modules/routing/webserver/webserver.c b/server/modules/routing/webserver/webserver.c index c9889ba77..f6546abb1 100644 --- a/server/modules/routing/webserver/webserver.c +++ b/server/modules/routing/webserver/webserver.c @@ -64,7 +64,8 @@ static ROUTER_OBJECT MyObject = diagnostic, NULL, NULL, - getCapabilities + getCapabilities, + NULL };