[Neo-report] r2823 jm - in /trunk/neo: admin/ lib/ master/ master/handlers/ neoctl/ storag...

nobody at svn.erp5.org nobody at svn.erp5.org
Mon Sep 5 18:24:54 CEST 2011


Author: jm
Date: Mon Sep  5 18:24:53 2011
New Revision: 2823

Log:
Fix resource leaks when nodes and threaded tests end

Modified:
    trunk/neo/admin/app.py
    trunk/neo/admin/handler.py
    trunk/neo/lib/event.py
    trunk/neo/lib/node.py
    trunk/neo/master/app.py
    trunk/neo/master/handlers/client.py
    trunk/neo/neoctl/app.py
    trunk/neo/neoctl/neoctl.py
    trunk/neo/storage/app.py
    trunk/neo/storage/handlers/__init__.py
    trunk/neo/storage/handlers/client.py
    trunk/neo/tests/threaded/__init__.py

Modified: trunk/neo/admin/app.py
==============================================================================
--- trunk/neo/admin/app.py [iso-8859-1] (original)
+++ trunk/neo/admin/app.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -79,6 +79,12 @@ class Application(object):
         self.reset()
         registerLiveDebugger(on_log=self.log)
 
+    def close(self):
+        self.listening_conn = None
+        self.nm.close()
+        self.em.close()
+        del self.__dict__
+
     def reset(self):
         self.bootstrapped = False
         self.master_conn = None

Modified: trunk/neo/admin/handler.py
==============================================================================
--- trunk/neo/admin/handler.py [iso-8859-1] (original)
+++ trunk/neo/admin/handler.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -113,11 +113,12 @@ class MasterEventHandler(EventHandler):
 
     def _connectionLost(self, conn):
         app = self.app
-        assert app.master_conn in (conn, None)
-        app.dispatcher.clear()
-        app.reset()
-        app.uuid = None
-        raise PrimaryFailure
+        if app.listening_conn: # if running
+            assert app.master_conn in (conn, None)
+            app.dispatcher.clear()
+            app.reset()
+            app.uuid = None
+            raise PrimaryFailure
 
     def connectionFailed(self, conn):
         self._connectionLost(conn)

Modified: trunk/neo/lib/event.py
==============================================================================
--- trunk/neo/lib/event.py [iso-8859-1] (original)
+++ trunk/neo/lib/event.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -30,6 +30,11 @@ class EpollEventManager(object):
         self.epoll = Epoll()
         self._pending_processing = []
 
+    def close(self):
+        for c in self.connection_dict.values():
+            c.close()
+        del self.__dict__
+
     def getConnectionList(self):
         # XXX: use index
         return [x for x in self.connection_dict.values() if not x.isAborted()]

Modified: trunk/neo/lib/node.py
==============================================================================
--- trunk/neo/lib/node.py [iso-8859-1] (original)
+++ trunk/neo/lib/node.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -26,6 +26,8 @@ from neo.lib import attributeTracker
 class Node(object):
     """This class represents a node."""
 
+    _connection = None
+
     def __init__(self, manager, address=None, uuid=None,
             state=NodeStates.UNKNOWN):
         self._state = state
@@ -33,7 +35,6 @@ class Node(object):
         self._uuid = uuid
         self._manager = manager
         self._last_state_change = time()
-        self._connection = None
         manager.add(self)
 
     def notify(self, packet):
@@ -88,7 +89,7 @@ class Node(object):
             Callback from node's connection when closed
         """
         assert self._connection is not None
-        self._connection = None
+        del self._connection
         self._manager._updateIdentified(self)
 
     def setConnection(self, connection):
@@ -261,6 +262,8 @@ class NodeManager(object):
         self._state_dict = {}
         self._identified_dict = {}
 
+    close = __init__
+
     def add(self, node):
         if node in self._node_set:
             neo.lib.logging.warning('adding a known node %r, ignoring', node)

Modified: trunk/neo/master/app.py
==============================================================================
--- trunk/neo/master/app.py [iso-8859-1] (original)
+++ trunk/neo/master/app.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -94,6 +94,12 @@ class Application(object):
 
         registerLiveDebugger(on_log=self.log)
 
+    def close(self):
+        self.listening_conn = None
+        self.nm.close()
+        self.em.close()
+        del self.__dict__
+
     def log(self):
         self.em.log()
         self.nm.log()

Modified: trunk/neo/master/handlers/client.py
==============================================================================
--- trunk/neo/master/handlers/client.py [iso-8859-1] (original)
+++ trunk/neo/master/handlers/client.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -31,12 +31,13 @@ class ClientServiceHandler(MasterHandler
     def connectionLost(self, conn, new_state):
         # cancel its transactions and forgot the node
         app = self.app
-        node = app.nm.getByUUID(conn.getUUID())
-        assert node is not None
-        app.tm.abortFor(node)
-        node.setState(NodeStates.DOWN)
-        app.broadcastNodesInformation([node])
-        app.nm.remove(node)
+        if app.listening_conn: # if running
+            node = app.nm.getByUUID(conn.getUUID())
+            assert node is not None
+            app.tm.abortFor(node)
+            node.setState(NodeStates.DOWN)
+            app.broadcastNodesInformation([node])
+            app.nm.remove(node)
 
     def askNodeInformation(self, conn):
         # send informations about master and storages only

Modified: trunk/neo/neoctl/app.py
==============================================================================
--- trunk/neo/neoctl/app.py [iso-8859-1] (original)
+++ trunk/neo/neoctl/app.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -39,6 +39,9 @@ class TerminalNeoCTL(object):
     def __init__(self, address):
         self.neoctl = NeoCTL(address)
 
+    def __del__(self):
+        self.neoctl.close()
+
     # Utility methods (could be functions)
     def asNodeState(self, value):
         return NodeStates.getByName(value.upper())

Modified: trunk/neo/neoctl/neoctl.py
==============================================================================
--- trunk/neo/neoctl/neoctl.py [iso-8859-1] (original)
+++ trunk/neo/neoctl/neoctl.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -38,6 +38,10 @@ class NeoCTL(object):
         self.handler = CommandEventHandler(self)
         self.response_queue = []
 
+    def close(self):
+        self.em.close()
+        del self.__dict__
+
     def __getConnection(self):
         if not self.connected:
             self.connection = ClientConnection(self.em, self.handler,

Modified: trunk/neo/storage/app.py
==============================================================================
--- trunk/neo/storage/app.py [iso-8859-1] (original)
+++ trunk/neo/storage/app.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -88,6 +88,12 @@ class Application(object):
 
         registerLiveDebugger(on_log=self.log)
 
+    def close(self):
+        self.listening_conn = None
+        self.nm.close()
+        self.em.close()
+        del self.__dict__
+
     def _poll(self):
         self.em.poll(1)
 

Modified: trunk/neo/storage/handlers/__init__.py
==============================================================================
--- trunk/neo/storage/handlers/__init__.py [iso-8859-1] (original)
+++ trunk/neo/storage/handlers/__init__.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -26,7 +26,8 @@ from neo.lib.protocol import NodeStates,
 class BaseMasterHandler(EventHandler):
 
     def connectionLost(self, conn, new_state):
-        raise PrimaryFailure('connection lost')
+        if self.app.listening_conn: # if running
+            raise PrimaryFailure('connection lost')
 
     def stopOperation(self, conn):
         raise OperationFailure('operation stopped')

Modified: trunk/neo/storage/handlers/client.py
==============================================================================
--- trunk/neo/storage/handlers/client.py [iso-8859-1] (original)
+++ trunk/neo/storage/handlers/client.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -36,8 +36,9 @@ class ClientOperationHandler(BaseClientA
     def connectionLost(self, conn, new_state):
         uuid = conn.getUUID()
         node = self.app.nm.getByUUID(uuid)
-        assert node is not None, conn
-        self.app.nm.remove(node)
+        if self.app.listening_conn: # if running
+            assert node is not None, conn
+            self.app.nm.remove(node)
 
     def abortTransaction(self, conn, ttid):
         self.app.tm.abort(ttid)

Modified: trunk/neo/tests/threaded/__init__.py
==============================================================================
--- trunk/neo/tests/threaded/__init__.py [iso-8859-1] (original)
+++ trunk/neo/tests/threaded/__init__.py [iso-8859-1] Mon Sep  5 18:24:53 2011
@@ -16,7 +16,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
-import os, random, socket, sys, tempfile, threading, time, types
+import os, random, socket, sys, tempfile, threading, time, types, weakref
 from collections import deque
 from functools import wraps
 from Queue import Queue, Empty
@@ -367,8 +367,9 @@ class NEOCluster(object):
         ip = getVirtualIp('master')
         self.master_nodes = ' '.join('%s:%s' % (ip, i)
                                      for i in xrange(master_count))
-        kw = dict(cluster=self, getReplicas=replicas, getPartitions=partitions,
-                  getAdapter=adapter, getReset=clear_databases)
+        weak_self = weakref.proxy(self)
+        kw = dict(cluster=weak_self, getReplicas=replicas, getAdapter=adapter,
+                  getPartitions=partitions, getReset=clear_databases)
         self.master_list = [MasterApplication(address=(ip, i), **kw)
                             for i in xrange(master_count)]
         ip = getVirtualIp('storage')
@@ -383,8 +384,8 @@ class NEOCluster(object):
                              for i, x in enumerate(db_list)]
         ip = getVirtualIp('admin')
         self.admin_list = [AdminApplication(address=(ip, 0), **kw)]
-        self.client = ClientApplication(self)
-        self.neoctl = NeoCTL(self)
+        self.client = ClientApplication(weak_self)
+        self.neoctl = NeoCTL(weak_self)
 
     # A few shortcuts that work when there's only 1 master/storage/admin
     @property
@@ -493,6 +494,13 @@ class NEOCluster(object):
         txn = transaction.TransactionManager()
         return txn, self.db.open(transaction_manager=txn)
 
+    def __del__(self):
+        self.neoctl.close()
+        for node_type in 'admin', 'storage', 'master':
+            for node in getattr(self, node_type + '_list'):
+                node.close()
+        self.client.em.close()
+
 
 class NEOThreadedTest(NeoTestBase):
 




More information about the Neo-report mailing list