Mike Gibson <notmikegibson@gmail.com> writes:
Greetings,
Hi, sorry for taking a few days to get back to you:
I'm using the MariaDB Non-blocking API to write a C++ client, but I've hit a wall regarding connection checking. I've been referencing the binding from node-mariasql ( https://github.com/mscdex/node-mariasql/blob/master/src/binding.cc).
Ok, great that you can use the non-blocking API!
The problem I'm experiencing is if I have a connection and kill the server (/etc/init.d/mysql stop) and then start it back (/etc/init.d/mysql start), I can never get clean reconnects. It's usually a mixture of errcode 2058, 2003, 2013.
I'm really confused how to gracefully manage connections. Before I was using the official MySQL C++ connector, and it provides a connection->isConnected() method. I'm wondering how I can get something similar with MariaDB's client, as I need the non-blocking interface.
I am not familiar with the MySQL C++ connector. I tried downloading the source for mysql-connector-c++-1.1.3.tar.gz, but it does not seem to have any isConnected() method? Anyway, the usual way to do this is to issue a mysql_ping() to the server, to check if the connection is working. With the non-blocking API, you would do this with mysql_ping_start() and mysql_ping_cont(). This will issue a request to the server to check if the connection is ok. If you have autoconnect enabled (MYSQL_OPT_RECONNECT), then this will automatically reconnect if the old connection was broken for some reason. (Note that you will need to be aware of the usual issues with automatic reconnect. For example, even if ping is successful, the connection may break immediately afterwards. And an autoconnect will loose any existing state on the connection such as temporary tables, SET @user_var, BEGIN, etc.)
Given: MYSQL mysql, *mysqlHandle;
Look at the mysql_real_connect_start() or cont() functions. I provide MYSQL struct and on connect I get a copy of the struct stored in *mysqlHandle. It's not clear to me what the purpose of the copy is at this point as I still use the initial struct to call query().
Agree, it is not very useful, it is just a copy of the pointer to your own structure. You only need it to check for error (in which case the pointer will be NULL). After that you can just you the pointer to your own struct that you already have.
In the case that I can detect a disconnection, how do I properly clean up the connection and attempt reconnect? Do I mysql_close(&mysql) and/or mysql_close(mysqlHandle), shutdown/close the file descriptor, mysql_init() a new handle and go through mysql_real_connect_start/cont()?
I am not sure, but it seems to me from looking at the code that if you already got an error that the connection was closed, then you can just go through the mysql_real_connect_start/cont() sequence again to reconnect. But if that does not work, you can always mysql_close() and mysql_init() your struct again. There is no need to explicitly shutdown or close the file descriptor.
Does it even make sense for each object to have its own MYSQL struct that I mysql_init(), or would it be better to have layer on top that mysql_init()s a single MYSQL struct, connects, and passes the returned *mysqlHandle to each query?
This depends on your application. You can only have a single query in progress on one MYSQL struct at a time. So if you have multiple queries working at the same time on the server, you need one MYSQL struct for each. If you only have one query processing at a time, a single MYSQL struct will be sufficient.
Thanks for providing the async client, any help is appreciated.
I hope this helps, though it is of a somewhat generic nature. If you need more details, please ask again, perhaps with some example code that shows your problems. - Kristian.