[glom] Self-hosting: Attempt to avoid failed shutdowns.



commit 1ef1e126fabbe89e66f1fed01aa1b875bc3dfcb6
Author: Murray Cumming <murrayc murrayc com>
Date:   Wed Oct 19 11:20:07 2011 +0200

    Self-hosting: Attempt to avoid failed shutdowns.
    
    * glom/libglom/connectionpool.cc: invalidate_connection(): Actually call
    Gda::Connection::close() instead of relying on the Connection destructor to
    do that, because maybe it is not closing it if maybe Connection::is_opened()
    is not working correctly.
    cleanup(): invalidate the connection before shutting down the server,
    not after, in case an open connection is stopping the server from closing down.
    * glom/libglom/connectionpool_backends/postgres_self.[h|cc]:
    connect(): Remember the connection details so we can use them later to show
    debug output.
    Added show_active_connections() to try to get a clue about what is wrong
    when the shutdown fails, using those connection details.
    cleanup(): Call it when the shutdown fails.

 ChangeLog                                          |   17 ++++++
 glom/libglom/connectionpool.cc                     |   16 ++++--
 .../connectionpool_backends/postgres_self.cc       |   57 +++++++++++++++++++-
 .../connectionpool_backends/postgres_self.h        |    6 ++
 4 files changed, 90 insertions(+), 6 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 86418c3..caaacef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2011-10-19  Murray Cumming  <murrayc murrayc com>
 
+	Self-hosting: Attempt to avoid failed shutdowns.
+
+	* glom/libglom/connectionpool.cc: invalidate_connection(): Actually call
+	Gda::Connection::close() instead of relying on the Connection destructor to
+	do that, because maybe it is not closing it if maybe Connection::is_opened()
+	is not working correctly.
+	cleanup(): invalidate the connection before shutting down the server,
+	not after, in case an open connection is stopping the server from closing down. 
+	* glom/libglom/connectionpool_backends/postgres_self.[h|cc]:
+	connect(): Remember the connection details so we can use them later to show
+	debug output.
+	Added show_active_connections() to try to get a clue about what is wrong
+	when the shutdown fails, using those connection details.
+	cleanup(): Call it when the shutdown fails.
+
+2011-10-19  Murray Cumming  <murrayc murrayc com>
+
 	Fix make check.
 
 	* tests/test_selfhosting_new_from_example.cc: Add some missing !.
diff --git a/glom/libglom/connectionpool.cc b/glom/libglom/connectionpool.cc
index e83ea48..053012b 100644
--- a/glom/libglom/connectionpool.cc
+++ b/glom/libglom/connectionpool.cc
@@ -86,8 +86,9 @@ SharedConnection::type_signal_finished SharedConnection::signal_finished()
 void SharedConnection::close()
 {
   if(m_gda_connection)
+  {
     m_gda_connection.reset();
-
+  }
 
   //Tell the connection pool that we have finished with this connection.
   //It might want to close it, or keep it open if somebody else is using it.
@@ -492,6 +493,10 @@ void ConnectionPool::invalidate_connection()
   connection_cached.clear();
   connection_cached_timeout_connection.disconnect();
   connection_cached_finished_connection.disconnect();
+
+  if(m_refGdaConnection)
+    m_refGdaConnection->close();
+    
   m_refGdaConnection.reset();
   m_sharedconnection_refcount = 0;
 }
@@ -622,13 +627,14 @@ bool ConnectionPool::cleanup(const SlotProgress& slot_progress)
 
   bool result = false;
 
+  //Make sure that no connections are still open.
+  //Otherwise database shutdown could fail.
+  //And make sure that connect() tries to make a new connection:
+  invalidate_connection();
+      
   if(m_backend.get())
     result = m_backend->cleanup(slot_progress);
 
-  //Make sure that connect() tries to make a new connection:
-  invalidate_connection();
-
-
 #ifndef G_OS_WIN32
   /* Stop advertising the self-hosting database server via avahi: */
   //avahi_stop_publishing();
diff --git a/glom/libglom/connectionpool_backends/postgres_self.cc b/glom/libglom/connectionpool_backends/postgres_self.cc
index c90592d..b7ff22b 100644
--- a/glom/libglom/connectionpool_backends/postgres_self.cc
+++ b/glom/libglom/connectionpool_backends/postgres_self.cc
@@ -19,7 +19,9 @@
  */
 
 #include <libglom/connectionpool_backends/postgres_self.h>
+#include <libglom/connectionpool.h>
 #include <libglom/utils.h>
+#include <libglom/db_utils.h>
 #include <libglom/spawn_with_feedback.h>
 #include <giomm.h>
 #include <glib/gstdio.h> // For g_remove
@@ -451,6 +453,44 @@ Backend::StartupErrors PostgresSelfHosted::startup(const SlotProgress& slot_prog
   return STARTUPERROR_NONE;
 }
 
+void PostgresSelfHosted::show_active_connections()
+{
+  Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+      Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+  builder->select_add_field("*", "pg_stat_activity");
+  builder->select_add_target("pg_stat_activity");
+ 
+  Glib::RefPtr<Gnome::Gda::Connection> gda_connection = connect(m_saved_database_name, m_saved_username, m_saved_password);
+  if(!gda_connection)
+    std::cerr << G_STRFUNC << ": connection failed." << std::endl;
+  
+  Glib::RefPtr<Gnome::Gda::DataModel> datamodel = DbUtils::query_execute_select(builder);
+  if(!datamodel)
+    std::cerr << G_STRFUNC << ": pg_stat_activity SQL query failed." << std::endl;
+  
+  const int rows_count = datamodel->get_n_rows(); 
+  if(datamodel->get_n_rows() < 1)
+    std::cerr << G_STRFUNC << ": pg_stat_activity SQL query returned no rows." << std::endl;
+
+  std::cout << "Active connections according to a pg_stat_activity SQL query:" << std::endl;
+  const int cols_count = datamodel->get_n_columns();
+  for(int row = 0; row < rows_count; ++row)
+  {
+    for(int col = 0; col < cols_count; ++col)
+    {
+      if(col != 0)
+        std::cout << ", ";
+        
+      std::cout << datamodel->get_value_at(col, row).to_string();
+    }
+    
+    std::cout << std::endl;
+  }
+  
+  //Make sure that this connection does not stop a further attempt to stop the server.
+  gda_connection->close();
+}
+
 bool PostgresSelfHosted::cleanup(const SlotProgress& slot_progress)
 {
   // This seems to be called twice sometimes, so we don't assert here until
@@ -482,7 +522,17 @@ bool PostgresSelfHosted::cleanup(const SlotProgress& slot_progress)
   if(!result)
   {
     std::cerr << "Error while attempting to stop self-hosting of the database. Trying again."  << std::endl;
-
+    
+    //Show open connections for debugging:
+    try
+    {
+      show_active_connections();
+    }
+    catch(const Glib::Error& ex)
+    {
+      std::cerr << G_STRFUNC << ": exception while trying to show active connections: " << ex.what() << std::endl;
+    }
+    
     //I've seen it fail when running under valgrind, and there are reports of failures in bug #420962.
     //Maybe it will help to try again:
     const bool result = Glom::Spawn::execute_command_line_and_wait(command_postgres_stop, slot_progress);
@@ -601,6 +651,11 @@ Glib::RefPtr<Gnome::Gda::Connection> PostgresSelfHosted::connect(const Glib::ust
     keep_trying = false;
   }
 
+  //Save the connection details _only_ for later debug use:
+  
+  m_saved_database_name = database;
+  m_saved_username = username;
+  m_saved_password = password;
   return result;
 }
 
diff --git a/glom/libglom/connectionpool_backends/postgres_self.h b/glom/libglom/connectionpool_backends/postgres_self.h
index f3010a9..b36f750 100644
--- a/glom/libglom/connectionpool_backends/postgres_self.h
+++ b/glom/libglom/connectionpool_backends/postgres_self.h
@@ -78,8 +78,14 @@ private:
   Glib::ustring get_postgresql_utils_version(const SlotProgress& slot_progress);
 
   float get_postgresql_utils_version_as_number(const SlotProgress& slot_progress);
+  
+  void show_active_connections();
 
   bool m_network_shared;
+  
+  //These are only remembered in order to use them to provide debug
+  //information when the PostgreSQL shutdown fails:
+  Glib::ustring m_saved_database_name, m_saved_username, m_saved_password;
 };
 
 } // namespace ConnectionPoolBackends



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]