From 26187bfc8166a868b77cb4f65301cc3ba29f786a Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Thu, 8 May 2008 18:02:55 -0700 Subject: [PATCH] use a weakref cache in the client to manage singleton filenodes/dirnodes, to avoid autocollision. Should close #391. --- src/allmydata/client.py | 30 ++++++++++++++++++------------ src/allmydata/test/test_system.py | 2 ++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/allmydata/client.py b/src/allmydata/client.py index 95cd8ff7..82c97735 100644 --- a/src/allmydata/client.py +++ b/src/allmydata/client.py @@ -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, diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index 60aa97d6..5dad8bb7 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -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) -- 2.45.2