use a weakref cache in the client to manage singleton filenodes/dirnodes, to avoid autocollision. Should close #391.

This commit is contained in:
Brian Warner 2008-05-08 18:02:55 -07:00
parent 8f4e409677
commit 26187bfc81
2 changed files with 20 additions and 12 deletions

View 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,

View 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)