On Thursday 28 December 2006 20:36, Oleg Broytmann wrote:
> On Thu, Dec 28, 2006 at 06:56:08PM +0100, Markus Gritsch wrote:
> > Since there was no comment on the e-mail below, I resend it in case
> > it got lost.
>
>    Sorry for the silence. I have got it the first time. Just don't have
> time to work on it. There are other patches to test; I am working on
> the patch that implements delColumn and fromDatabase for SQLite.
>    Regarding the patch. I think to fix the problem I will replace
> "while 1" with "for i in range(1000): sleep(1)". There should be no
> "raise", or the loop would be meaningless at all. The idea of the loop
> is to wait until the server is restarted.

I disagree with you here. It's a bad design to let SQLObject (a library) 
make this decision (what to do and how long to wait when a connection is 
lost and cannot be reestablished).

I agree that SQLObject should attempt to reconnect, for cases where the 
server was restarted or the connection was lost because it was idle too 
long. But if it can't reconnect immediately it should signal this error 
to the caller (application). This reconnect is only to avoid extra hassle 
in the application for something that can be done automatically and takes 
no extra time.

Trying to reconnect forever or for long periods of time is a bad thing. 
Just imagine the scenario where I have a realtime application using 
sqlobject and a replicated master-slave database. If the master dies, or 
is taken out for maintenance, I want the application to commute to the 
slave database as quickly as possible (as soon as it finds out that the 
connection was lost). With the original code or your proposal I cannot do 
this and my application will block waiting for sqlobject to do something 
it cannot do because it has no knowledge of the situation or what the 
application intends to do in such cases.

Attached is a patch that fixes this in a better way. It still allows 
reconnects if the database connection was lost because of a server 
restart or the connection being closed because it was idle too long, but 
will allow the application to make decisions on its own if the database 
is down for good and cannot be reconnected.

-- 
Dan
Index: mysqlconnection.py
===================================================================
--- mysqlconnection.py	(revision 2165)
+++ mysqlconnection.py	(working copy)
@@ -78,7 +78,19 @@
             conn.autocommit(auto)
 
     def _executeRetry(self, conn, cursor, query):
-        while 1:
+        # When a server connection is lost and a query is attempted, most of
+        # the time the query will raise a SERVER_LOST exception, then at the
+        # second attempt to execute it, the mysql lib will reconnect and
+        # succeed. However is a few cases, the first attempt raises the
+        # SERVER_GONE exception, the second attempt the SERVER_LOST exception
+        # and only the third succeeds. Thus the 3 in the loop count.
+        # If it doesn't reconnect even after 3 attempts, while the database is
+        # up and running, it is because a 5.0.x (or newer) server is used
+        # which no longer permits autoreconnects by default. In their case a
+        # reconnect flag must be set when making the connection to indicate
+        # that autoreconnecting is desired and the python-mysqldb module
+        # doesn't set this flag.
+        for c in range(0, 3):
             try:
                 if self.need_unicode:
                     # For MysqlDB 1.2.1 and later, we go
@@ -88,7 +100,9 @@
                 else:
                     return cursor.execute(query)
             except MySQLdb.OperationalError, e:
-                if e.args[0] == 2013: # SERVER_LOST error
+                if e.args[0] in (2006, 2013): # SERVER_GONE or SERVER_LOST error
+                    if c == 2:
+                        raise OperationalError(ErrorMessage(e))
                     if self.debug:
                         self.printDebug(conn, str(e), 'ERROR')
                 else:
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss

Reply via email to