aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-02-21 12:06:03 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-02-21 12:06:03 +0200
commit81c2f16a9826d92cf5b54da71f70943263878d3e (patch)
treee71b970490eca51a515e4d1f259e543f20b68bb9
parent6c85f1a50e3b50d18599143e18ee145fc6afdb08 (diff)
Validate connection in MySQL pool factory
This will help deal with the MySQL server closing connections after a certain period of inactivity.
-rw-r--r--odb/mysql/connection-factory.cxx6
-rw-r--r--odb/mysql/connection-factory.hxx8
-rw-r--r--odb/mysql/connection.cxx26
-rw-r--r--odb/mysql/connection.hxx7
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<pooled_connection> 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 <odb/mysql/database.hxx>
#include <odb/mysql/connection.hxx>
+#include <odb/mysql/error.hxx>
#include <odb/mysql/exceptions.hxx>
#include <odb/mysql/statement-cache.hxx>
@@ -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 ()