use a weakref cache in the client to manage singleton filenodes/dirnodes, to avoid...
authorBrian Warner <warner@allmydata.com>
Fri, 9 May 2008 01:02:55 +0000 (18:02 -0700)
committerBrian Warner <warner@allmydata.com>
Fri, 9 May 2008 01:02:55 +0000 (18:02 -0700)
src/allmydata/client.py
src/allmydata/test/test_system.py

index 95cd8ff77a9021abc6842b96043e6f0189ec76d5..82c9773576230419bd577e091f70f46f4764ab47 100644 (file)
@@ -1,5 +1,5 @@
 
-import os, stat, time, re
+import os, stat, time, re, weakref
 from allmydata.interfaces import RIStorageServer
 from allmydata import node
 
@@ -170,6 +170,7 @@ class Client(node.Node, testutil.PollMixin):
         helper_furl = self.get_config("helper.furl")
         convergence_s = self.get_or_create_private_config('convergence', _make_secret)
         self.convergence = base32.a2b(convergence_s)
+        self._node_cache = weakref.WeakValueDictionary() # uri -> node
         self.add_service(Uploader(helper_furl, self.stats_provider))
         self.add_service(Downloader(self.stats_provider))
         self.add_service(Checker())
@@ -292,17 +293,22 @@ class Client(node.Node, testutil.PollMixin):
     def create_node_from_uri(self, u):
         # this returns synchronously.
         u = IURI(u)
-        if IReadonlyNewDirectoryURI.providedBy(u):
-            # new-style read-only dirnodes
-            return NewDirectoryNode(self).init_from_uri(u)
-        if INewDirectoryURI.providedBy(u):
-            # new-style dirnodes
-            return NewDirectoryNode(self).init_from_uri(u)
-        if IFileURI.providedBy(u):
-            # CHK
-            return FileNode(u, self)
-        assert IMutableFileURI.providedBy(u), u
-        return MutableFileNode(self).init_from_uri(u)
+        u_s = u.to_string()
+        if u_s not in self._node_cache:
+            if IReadonlyNewDirectoryURI.providedBy(u):
+                # new-style read-only dirnodes
+                node = NewDirectoryNode(self).init_from_uri(u)
+            elif INewDirectoryURI.providedBy(u):
+                # new-style dirnodes
+                node = NewDirectoryNode(self).init_from_uri(u)
+            elif IFileURI.providedBy(u):
+                # CHK
+                node = FileNode(u, self)
+            else:
+                assert IMutableFileURI.providedBy(u), u
+                node = MutableFileNode(self).init_from_uri(u)
+            self._node_cache[u_s] = node
+        return self._node_cache[u_s]
 
     def notify_publish(self, publish_status, size):
         self.getServiceNamed("mutable-watcher").notify_publish(publish_status,
index 60aa97d617ea0d658498c479f5b70dccd54f0b44..5dad8bb7ba9d15e13d16ab2dde484eaf8fefde41 100644 (file)
@@ -702,6 +702,8 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, testutil.StallMixin,
             uri = self._mutable_node_1.get_uri()
             log.msg("starting retrieve1")
             newnode = self.clients[0].create_node_from_uri(uri)
+            newnode_2 = self.clients[0].create_node_from_uri(uri)
+            self.failUnlessIdentical(newnode, newnode_2)
             return newnode.download_best_version()
         d.addCallback(_check_download_1)