From 81c2f16a9826d92cf5b54da71f70943263878d3e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 21 Feb 2011 12:06:03 +0200 Subject: Validate connection in MySQL pool factory This will help deal with the MySQL server closing connections after a certain period of inactivity. --- odb/mysql/connection-factory.cxx | 6 +++++- odb/mysql/connection-factory.hxx | 8 +++++++- odb/mysql/connection.cxx | 26 ++++++++++++++++++++++++++ odb/mysql/connection.hxx | 7 +++++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/odb/mysql/connection-factory.cxx b/odb/mysql/connection-factory.cxx index b9b3d19..2f1b00c 100644 --- a/odb/mysql/connection-factory.cxx +++ b/odb/mysql/connection-factory.cxx @@ -178,8 +178,12 @@ namespace odb if (connections_.size () != 0) { shared_ptr c (connections_.back ()); - c->pool_ = this; connections_.pop_back (); + + if (ping_ && !c->ping ()) + continue; + + c->pool_ = this; in_use_++; return c; } diff --git a/odb/mysql/connection-factory.hxx b/odb/mysql/connection-factory.hxx index d9dbf80..43d6f9f 100644 --- a/odb/mysql/connection-factory.hxx +++ b/odb/mysql/connection-factory.hxx @@ -80,10 +80,15 @@ namespace odb // value is 0 then the pool will maintain all the connections // that were ever created. // + // The ping argument specifies whether to ping the connection to + // make sure it is still alive before returning it to the caller. + // connection_pool_factory (std::size_t max_connections = 0, - std::size_t min_connections = 0) + std::size_t min_connections = 0, + bool ping = true) : max_ (max_connections), min_ (min_connections), + ping_ (ping), in_use_ (0), waiters_ (0), db_ (0), @@ -134,6 +139,7 @@ namespace odb private: const std::size_t max_; const std::size_t min_; + const bool ping_; std::size_t in_use_; // Number of connections currently in use. std::size_t waiters_; // Number of threads waiting for a connection. diff --git a/odb/mysql/connection.cxx b/odb/mysql/connection.cxx index 7679e27..98fd427 100644 --- a/odb/mysql/connection.cxx +++ b/odb/mysql/connection.cxx @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -66,6 +67,31 @@ namespace odb mysql_close (handle_); } + bool connection:: + ping () + { + if (failed ()) + return false; + + if (!mysql_ping (handle_)) + return true; + + switch (mysql_errno (handle_)) + { + case CR_SERVER_LOST: + case CR_SERVER_GONE_ERROR: + { + mark_failed (); + return false; + } + default: + { + translate_error (*this); + return false; // Never reached. + } + } + } + MYSQL_STMT* connection:: alloc_stmt_handle () { diff --git a/odb/mysql/connection.hxx b/odb/mysql/connection.hxx index 6704f23..16d3438 100644 --- a/odb/mysql/connection.hxx +++ b/odb/mysql/connection.hxx @@ -58,6 +58,13 @@ namespace odb failed_ = true; } + // Ping the server to make sure the connection is still alive. Return + // true if successful, mark the connection as failed and return false + // otherwise. This function can also throw database_exception. + // + bool + ping (); + public: MYSQL* handle () -- cgit v1.1