lazily create DownloadNode upon first read()/get_segment()
authorBrian Warner <warner@lothar.com>
Wed, 4 Aug 2010 07:28:08 +0000 (00:28 -0700)
committerBrian Warner <warner@lothar.com>
Wed, 4 Aug 2010 07:28:08 +0000 (00:28 -0700)
src/allmydata/immutable/filenode.py
src/allmydata/test/test_download.py
src/allmydata/test/test_hung_server.py

index 1d5be94867bce4a639f8e203172163530e274db7..44c8e95e502309366588a5820cb9bf0963a8d21e 100644 (file)
@@ -31,14 +31,24 @@ class CiphertextFileNode:
             if history:
                 history.add_download(ds)
             download_status = ds
-        self._node = DownloadNode(verifycap, storage_broker, secret_holder,
-                                  terminator, history, download_status)
+        self._terminator = terminator
+        self._history = history
+        self._download_status = download_status
+        self._node = None # created lazily, on read()
+
+    def _maybe_create_download_node(self):
+        if self._node is None:
+            self._node = DownloadNode(self._verifycap, self._storage_broker,
+                                      self._secret_holder,
+                                      self._terminator,
+                                      self._history, self._download_status)
 
     def read(self, consumer, offset=0, size=None, read_ev=None):
         """I am the main entry point, from which FileNode.read() can get
         data. I feed the consumer with the desired range of ciphertext. I
         return a Deferred that fires (with the consumer) when the read is
         finished."""
+        self._maybe_create_download_node()
         return self._node.read(consumer, offset, size, read_ev)
 
     def get_segment(self, segnum):
@@ -56,10 +66,12 @@ class CiphertextFileNode:
         segment, so that you can call get_segment() before knowing the
         segment size, and still know which data you received.
         """
+        self._maybe_create_download_node()
         return self._node.get_segment(segnum)
 
     def get_segment_size(self):
         # return a Deferred that fires with the file's real segment size
+        self._maybe_create_download_node()
         return self._node.get_segsize()
 
     def get_storage_index(self):
index 570a1df1bc2ff8c99b1e4d1c765244d674371806..42d3c696c20956eb9b97d8ef0ffa0a25dd4dbda5 100644 (file)
@@ -327,6 +327,7 @@ class DownloadTest(_Base, unittest.TestCase):
         self.c0 = self.g.clients[0]
         self.load_shares()
         n = self.c0.create_node_from_uri(immutable_uri)
+        n._cnode._maybe_create_download_node()
 
         # Cause the downloader to guess a segsize that's too low, so it will
         # ask for a segment number that's too high (beyond the end of the
@@ -385,6 +386,7 @@ class DownloadTest(_Base, unittest.TestCase):
         d = self.c0.upload(u)
         def _uploaded(ur):
             n = self.c0.create_node_from_uri(ur.uri)
+            n._cnode._maybe_create_download_node()
             n._cnode._node._build_guessed_tables(u.max_segment_size)
             d1 = n.read(con1, 70, 20)
             #d2 = n.read(con2, 140, 20) # XXX
@@ -413,6 +415,7 @@ class DownloadTest(_Base, unittest.TestCase):
         d = self.c0.upload(u)
         def _uploaded(ur):
             n = self.c0.create_node_from_uri(ur.uri)
+            n._cnode._maybe_create_download_node()
             n._cnode._node._build_guessed_tables(u.max_segment_size)
             d = n.read(con1, 12000, 20)
             def _read1(ign):
@@ -620,6 +623,7 @@ class DownloadTest(_Base, unittest.TestCase):
         d = self.c0.upload(u)
         def _uploaded(ur):
             n = self.c0.create_node_from_uri(ur.uri)
+            n._cnode._maybe_create_download_node()
             n._cnode._node._build_guessed_tables(u.max_segment_size)
 
             d = download_to_data(n)
@@ -658,6 +662,7 @@ class DownloadTest(_Base, unittest.TestCase):
         d = self.c0.upload(u)
         def _uploaded(ur):
             n = self.c0.create_node_from_uri(ur.uri)
+            n._cnode._maybe_create_download_node()
             n._cnode._node._build_guessed_tables(u.max_segment_size)
             d1 = n.read(con1, 70, 20)
             #d2 = n.read(con2, 140, 20)
@@ -805,6 +810,7 @@ class Corruption(_Base, unittest.TestCase):
 
         def _download(ign, imm_uri, which, expected):
             n = self.c0.create_node_from_uri(imm_uri)
+            n._cnode._maybe_create_download_node()
             # for this test to work, we need to have a new Node each time.
             # Make sure the NodeMaker's weakcache hasn't interfered.
             assert not n._cnode._node._shares
@@ -945,6 +951,7 @@ class Corruption(_Base, unittest.TestCase):
                           ]
             def _download(imm_uri):
                 n = self.c0.create_node_from_uri(imm_uri)
+                n._cnode._maybe_create_download_node()
                 # for this test to work, we need to have a new Node each time.
                 # Make sure the NodeMaker's weakcache hasn't interfered.
                 assert not n._cnode._node._shares
index 24dc84671f90fae56a8e2de79ef4bbc9ad5eb8bb..bc331c211a9997e1cabefb6dcd77dd3db9130dec 100644 (file)
@@ -231,6 +231,7 @@ class HungServerDownloadTest(GridTestMixin, ShouldFailMixin, PollMixin,
         def _reduce_max_outstanding_requests_and_download(ign):
             self._hang_shares(range(5))
             n = self.c0.create_node_from_uri(self.uri)
+            n._cnode._maybe_create_download_node()
             self._sf = n._cnode._node._sharefinder
             self._sf.max_outstanding_requests = 5
             self._sf.OVERDUE_TIMEOUT = 1000.0